Skip to main content
This guide walks you through cloning the Hayon monorepo, configuring both the backend and frontend, and publishing your first post. The entire setup takes around 10–15 minutes if you already have the required services installed.

Prerequisites

Before you start, make sure the following are available on your machine:
Hayon uses pnpm workspaces. Install Node.js from nodejs.org (v20 LTS recommended), then install pnpm:
npm install -g pnpm
Verify both:
node --version   # v20.x.x or higher
pnpm --version   # 9.x.x or higher
Hayon stores all application data in MongoDB. You can run it locally or use MongoDB Atlas.To run locally, follow the MongoDB installation guide for your OS, then start the service:
# macOS (Homebrew)
brew services start mongodb-community

# Ubuntu / Debian
sudo systemctl start mongod
The default connection URI is mongodb://localhost:27017/hayon.
Redis is used for caching and session-related data. The backend connects using REDIS_HOST and REDIS_PORT.
# macOS (Homebrew)
brew services start redis

# Ubuntu / Debian
sudo systemctl start redis
Default: localhost:6379.
RabbitMQ processes all post and analytics jobs. Hayon requires the rabbitmq_delayed_message_exchange plugin for scheduled posts.
# macOS (Homebrew)
brew services start rabbitmq

# Ubuntu / Debian
sudo systemctl start rabbitmq-server
Enable the delayed message plugin:
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
If Redis or RabbitMQ are not running when the backend starts, background jobs will fail silently. The web server itself will still start, but post publishing and analytics fetching will not work.

Installation

1

Clone the repository

git clone https://github.com/devxtra-community/hayon.git
cd hayon
If you previously installed dependencies with npm, remove any node_modules directories and package-lock.json files before continuing. Hayon has migrated fully to pnpm.
2

Install all workspace dependencies

From the repository root, install dependencies for the entire monorepo at once:
pnpm install
This installs packages for both backend/ and frontend/ using pnpm workspaces.
3

Configure the backend environment

Create a .env file inside backend/:
cp backend/.env.example backend/.env
# or create it from scratch:
touch backend/.env
Populate it with the following variables:
# Core
NODE_ENV=development
PORT=5000
FRONTEND_URL=http://localhost:3000
BACKEND_URL=http://localhost:5000

# Database
MONGODB_URI=mongodb://localhost:27017/hayon

# JWT
ACCESS_TOKEN_SECRET=your-access-token-secret
REFRESH_TOKEN_SECRET=your-refresh-token-secret
JWT_EXPIRES_IN=7d

# Google OAuth
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
GOOGLE_CALLBACK_URL=http://localhost:5000/api/auth/google/callback

# Redis
REDIS_HOST=localhost
REDIS_PORT=6379

# RabbitMQ
RABBITMQ_URL=amqp://localhost:5672

# AWS S3
AWS_ACCESS_KEY_ID=your-access-key
AWS_SECRET_ACCESS_KEY=your-secret-key
AWS_REGION=your-region
AWS_S3_BUCKET_NAME=your-bucket-name

# Stripe
STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_PUBLISHABLE_KEY=pk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
STRIPE_PRO_PRICE_ID=price_xxx

# Email (Gmail)
[email protected]
EMAIL_PASS=your-app-password

# Meta (Facebook / Threads)
META_APP_ID=your-meta-app-id
META_APP_SECRET=your-meta-app-secret
META_REDIRECT_URI=http://localhost:5000/api/platform/facebook/callback

# Threads
THREADS_APP_ID=your-threads-app-id
THREADS_APP_SECRET=your-threads-app-secret
THREADS_REDIRECT_URI=http://localhost:5000/api/platform/threads/callback

# Tumblr
TUMBLR_CONSUMER_KEY=your-tumblr-consumer-key
TUMBLR_CONSUMER_SECRET=your-tumblr-consumer-secret

# Mastodon
MASTODON_CLIENT_KEY=your-mastodon-client-key
MASTODON_CLIENT_SECRET=your-mastodon-client-secret
MASTODON_CALLBACK_URL=http://localhost:5000/api/platform/mastodon/callback
MASTODON_INSTANCE_URL=https://mastodon.social

# AI
GEMINI_API_KEY=your-gemini-api-key

# Observability
BETTER_STACK_TOKEN=your-better-stack-token
You don’t need every API key to get started locally. The minimum required set for the server to boot is: NODE_ENV, PORT, FRONTEND_URL, BACKEND_URL, MONGODB_URI, ACCESS_TOKEN_SECRET, REFRESH_TOKEN_SECRET, GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_CALLBACK_URL, REDIS_HOST, REDIS_PORT, RABBITMQ_URL, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, AWS_S3_BUCKET_NAME, STRIPE_SECRET_KEY, STRIPE_PUBLISHABLE_KEY, STRIPE_WEBHOOK_SECRET, STRIPE_PRO_PRICE_ID, EMAIL_USER, EMAIL_PASS, META_APP_ID, META_APP_SECRET, META_REDIRECT_URI, THREADS_APP_ID, THREADS_APP_SECRET, THREADS_REDIRECT_URI, TUMBLR_CONSUMER_KEY, TUMBLR_CONSUMER_SECRET, MASTODON_CLIENT_KEY, MASTODON_CLIENT_SECRET, MASTODON_CALLBACK_URL, MASTODON_INSTANCE_URL, GEMINI_API_KEY, and BETTER_STACK_TOKEN. These are enforced as required in backend/src/config/env.ts.
4

Configure the frontend environment

Create a .env.local file inside frontend/:
NEXT_PUBLIC_API_BASE_URL=http://localhost:5000
NEXT_PUBLIC_GOOGLE_CLIENT_ID=your-google-client-id
NEXT_PUBLIC_API_BASE_URL is the base URL that the Next.js app uses for all API requests. It must match the BACKEND_URL you configured in the backend .env.
5

Start the backend server

cd backend
pnpm run dev
The Express server starts with nodemon for hot-reloading. On startup it:
  1. Connects to MongoDB
  2. Connects to Redis
  3. Connects to RabbitMQ and asserts all exchanges and queues
  4. Starts the analytics cron job (AnalyticsCronService)
  5. Initialises Socket.IO on the same HTTP/HTTPS server
You should see output similar to:
MongoDB is connected
Redis Client Connected
Connected to RabbitMQ
Development Server running on port 5000
In development mode the server uses HTTPS with a local certificate (dev.hayon.site+2.pem). If you don’t have this certificate, you can temporarily modify app.ts to use a plain HTTP server for local testing.
6

Start the background worker

Open a second terminal and start the worker process separately from the web server:
cd backend
pnpm run worker
The worker connects to RabbitMQ and begins listening on the social_posts and analytics_fetch queues. You should see:
Starting Worker Process...
Connected to Database
Connected to RabbitMQ
Exchange ready: post.exchange
Delayed exchange ready: post.delayed.exchange
DLX exchange ready: dlx.exchange
Analytics exchange ready: analytics.exchange
Queues ready: social_posts, analytics_fetch and others...
Queue bindings complete
Listening on queue: social_posts
Listening on queue: analytics_fetch
The web server and worker are independent processes. The web server enqueues jobs; the worker consumes them. Both must be running for posts to be published.
7

Start the frontend

Open a third terminal:
cd frontend
pnpm run dev
The Next.js development server starts on http://localhost:3000.

First login

Hayon supports two authentication methods:
  • Google OAuth — Click Sign in with Google on the login page. Passport.js handles the OAuth flow; on first login a new user record is created automatically in MongoDB.
  • Email / password — Register with an email address and password. An OTP verification email is sent via Nodemailer (Gmail).
If you sign up with email and then try to sign in with Google using the same address, you will receive an email_exists_different_provider error. Each email address is tied to one authentication provider.
After logging in you will land on the main dashboard. Your account starts on the Free plan (30 posts/month, 15 AI caption generations/month).

Connect a social platform

Before creating a post, connect at least one social media account:
1

Open Platform Settings

Navigate to Settings → Connected Platforms in the sidebar.
2

Authorise the platform

Click Connect next to the platform you want to add (Bluesky, Facebook, Threads, Tumblr, or Mastodon). You’ll be redirected to that platform’s OAuth consent screen.
3

Confirm the connection

After authorising, you’ll be redirected back to Hayon. The platform card will show a green connected indicator.

Create and publish your first post

1

Open the post composer

Click New Post in the top navigation or dashboard quick-action area.
2

Write your content

Type your post text in the composer. You can also upload an image, which Hayon will upload to AWS S3 and attach to the post payload.
3

Generate an AI caption (optional)

Click Generate Caption. Hayon sends your content to Google Gemini and returns platform-specific caption suggestions. Select the one you want or edit it freely.
Caption generation counts against your monthly allowance (15 on Free, 30 on Pro). The current usage is shown in the composer.
4

Select target platforms

Choose one or more connected platforms. Each platform you select will receive an independent job in the queue, so a failure on one platform does not block others.
5

Publish immediately or schedule

  • Publish now — The backend publishes a message to POST_EXCHANGE with no delay. The worker picks it up within seconds.
  • Schedule — Choose a future date and time. The backend publishes a message to POST_DELAYED_EXCHANGE with the appropriate delay header. RabbitMQ holds the message until the scheduled time, then routes it to the worker.
6

Monitor the result

After submission, return to the Posts list. Each post shows per-platform status badges: processing, completed, or failed. Real-time updates arrive via WebSocket without requiring a page refresh.If a post fails due to a transient network error, the worker automatically retries up to three times with exponential back-off before marking it as permanently failed.

Running both services together

If you prefer to start the backend and frontend with a single command from the repo root:
pnpm run dev
This starts the web server and the Next.js dev server concurrently, but does not start the worker. You still need to run pnpm run worker in a separate terminal in the backend/ directory.

Next steps

Architecture

Understand how the components connect and how jobs flow from creation to publishing.

Platform integrations

Read platform-specific setup guides for Bluesky, Facebook, Threads, Tumblr, and Mastodon.

Environment variables

Full reference for every environment variable the backend reads at startup.

Subscription plans

Understand Free vs Pro limits and how to upgrade via Stripe.

Build docs developers (and LLMs) love