Monorepo β Core Development
Use this guide when you want to contribute to the Open Saasframe core, work on platform features, or run a full demo of the platform. If you want to build a product app without touching the core, use the Standalone App guide instead.
- π macOS
- π§ Linux
- πͺ Windows
Prerequisitesβ
Install the following tools before continuing. Each step includes a verification command.
1. Gitβ
macOS may already have Git via Xcode Command Line Tools. Check with git --version. If it is missing, install the CLT:
xcode-select --install
Or install Git via Homebrew (see next step).
2. Homebrewβ
If Homebrew is not already installed:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Follow the post-install instructions printed by the script to add Homebrew to your shell PATH.
3. Node.js 26β
# Option A β Homebrew
brew install node@26
echo 'export PATH="/opt/homebrew/opt/node@26/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# Option B β nvm (manage multiple Node versions)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
# Close and reopen your terminal, then:
nvm install 26
nvm use 26
nvm alias default 26
Verify: node --version β v24.x.x
4. Yarn 4.12.0β
Corepack ships with Node.js. Enable it once per machine, then activate Yarn:
corepack enable
corepack prepare [email protected] --activate
Verify: yarn --version β 4.12.0
5. Docker Desktopβ
Download and install Docker Desktop for Mac. Start it after installation.
Verify:
docker --version
docker compose version
Infrastructure servicesβ
Docker Desktop runs PostgreSQL, Redis, and Meilisearch. Start them from the repository root after cloning (step below):
docker compose up -d
This starts:
- PostgreSQL 17 with the pgvector extension β port
5432 - Redis 7 β port
6379 - Meilisearch β port
7700
Clone and configureβ
git clone https://github.com/saasframe/saasframe.git
cd saasframe
git checkout develop
Copy the environment template:
cp apps/saasframe/.env.example apps/saasframe/.env
Edit apps/saasframe/.env and set at least these three variables:
DATABASE_URL=postgres://postgres:postgres@localhost:5432/saasframe
JWT_SECRET=change-me-dev-secret
REDIS_URL=redis://localhost:6379
Generate a strong JWT_SECRET:
openssl rand -hex 32
Install dependencies and bootstrapβ
yarn install
yarn build:packages
yarn generate
yarn build:packages # second run required β compiles generated scripts
yarn initialize
yarn initialize runs migrations, seeds roles, provisions an admin user, and loads demo CRM data. Add --no-examples to skip demo content. The admin credentials are printed at the end.
Start the appβ
yarn dev
Open http://localhost:3000/backend and sign in with the credentials printed by yarn initialize.
The compact runtime also serves a splash page at http://localhost:4000 with live startup progress. Press d while yarn dev is running to toggle raw log output.
On memory-constrained machines you can lower yarn dev's footprint by narrowing which workspace packages the watcher tracks with SF_WATCH_SCOPE (e.g. SF_WATCH_SCOPE=auto-optimized yarn dev). The active mode is printed with an emoji at startup. See Choosing which packages the watcher tracks for the full reference.
Upgrading an existing checkoutβ
git pull
yarn install
yarn db:migrate
yarn generate
yarn dev
Prerequisitesβ
1. Gitβ
# Debian / Ubuntu
sudo apt update && sudo apt install -y git
# Fedora / RHEL
sudo dnf install -y git
Verify: git --version
2. Node.js 26β
Use nvm to manage Node versions:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
Close and reopen your terminal, then:
nvm install 26
nvm use 26
nvm alias default 26
Verify: node --version β v24.x.x
3. Yarn 4.12.0β
corepack enable
corepack prepare [email protected] --activate
Verify: yarn --version β 4.12.0
4. Dockerβ
Option A β Docker Desktop for Linux (easiest, includes Compose): download here.
Option B β Docker Engine + Compose plugin:
# Debian / Ubuntu
sudo apt install -y docker.io docker-compose-v2
sudo usermod -aG docker $USER
newgrp docker # or log out and back in
Verify:
docker --version
docker compose version
Infrastructure servicesβ
docker compose up -d
Starts PostgreSQL 17 (with pgvector), Redis 7, and Meilisearch.
Clone and configureβ
git clone https://github.com/saasframe/saasframe.git
cd saasframe
git checkout develop
cp apps/saasframe/.env.example apps/saasframe/.env
Edit apps/saasframe/.env:
DATABASE_URL=postgres://postgres:postgres@localhost:5432/saasframe
JWT_SECRET=change-me-dev-secret
REDIS_URL=redis://localhost:6379
Generate a strong JWT_SECRET:
openssl rand -hex 32
Install dependencies and bootstrapβ
yarn install
yarn build:packages
yarn generate
yarn build:packages
yarn initialize
Start the appβ
yarn dev
Open http://localhost:3000/backend and sign in with the credentials printed by yarn initialize.
Upgrading an existing checkoutβ
git pull
yarn install
yarn db:migrate
yarn generate
yarn dev
One-command setup (recommended)β
The fastest path on Windows β including a completely clean machine with no Git, no Docker, and no Node.js β is the bundled launcher:
- Get the repo (clone it, or download the ZIP and extract it). On a bare machine you can even download just
start-windows.batβ it installs Git and clones the repo for you. - Double-click
scripts\windows\start-windows.bat.
The launcher installs missing prerequisites (Git, WSL2, Docker Desktop β no Node.js or Build Tools needed, everything runs in containers) using winget when it is available and falling back to a direct download of the official installers when it is not (so Windows LTSC / Server / locked-down images without the App Installer still work), reboots-and-resumes automatically when Windows requires it, generates .env secrets, prompts for an LLM provider API key (required β pass -SkipLlmPrompt on the underlying script to configure it later), then starts the fully containerized dev stack from docker-compose.fullapp.dev.yml: the app (:3000, hot reload), the MCP server (:3001), the OpenCode agent (:4096), plus PostgreSQL, Redis, and Meilisearch. It waits for everything to become healthy and prints URLs and superadmin credentials.
- First boot takes 10β20 minutes (the container installs, builds, and seeds); progress is streamed from the build splash on
http://localhost:4000. Subsequent starts take seconds. scripts\windows\stop-windows.batstops the stack (data survives in Docker volumes).- Re-running
start-windows.batis always safe β every step is idempotent. Useful flags on the underlying script (scripts\windows\start-dev.ps1):-Status,-Logs,-Restart,-Reset(deletes all data),-DryRun,-NonInteractive,-SkipLlmPrompt,-Rebuild,-IncludeNativeToolchain. - No administrator rights? The launcher elevates only to install missing prerequisites. If a container runtime + WSL2 are already present (e.g. provisioned by IT), it detects that and runs the whole flow without admin. On a machine where you can't elevate at all, run
powershell scripts\windows\start-dev.ps1 -NoAdminβ it skips every admin step (and downloads the repo as a ZIP when Git is missing) and, if the runtime/WSL2 aren't installed, tells you exactly what to ask IT for. - Rancher Desktop instead of Docker Desktop? Fully supported β common where Docker Desktop licensing is not permitted. The launcher auto-detects an existing Rancher Desktop (machine-wide or per-user install) and uses it; make sure it runs the dockerd (moby) engine (the launcher requests this itself via
rdctl). To install Rancher instead of Docker on a clean machine, pass-Runtime rancher. - IDE setup: edit the project folder with any Windows IDE (VS Code, JetBrains, Cursor) β hot reload flows through the bind mount, and WSL never enters your workflow (
/mnt/c/...is only how a WSL shell would see the disk; don't run the project from there). One caveat:node_moduleslives in a container volume, not on the host, so TypeScript IntelliSense/ESLint need one of: (a) VS Code β Dev Containers: Attach to Running Containerβ¦ on theappcontainer and open/app(recommended β full IntelliSense, zero host tooling), or (b) install Node 26 and runyarn installonce, purely to feed the editor (the app still runs in containers). Power users who want maximum filesystem performance can use the full WSL2-native guide instead. - Blocked downloads / air-gapped? Drop the official installers (Git for Windows, Docker Desktop or Rancher Desktop,
wsl_update_x64.msi) into aninstallersfolder in the repository root (or next to the launcher scripts) (or pointSF_INSTALLERS_DIRat them) β the launcher validates and uses them without any network access. winget is never required.
The sections below cover the native (non-Docker) toolchain as an alternative for contributors who prefer running the app directly on Windows.
For the best developer experience on Windows β native Linux tooling, faster file I/O, full Docker support β use WSL2 with Ubuntu instead of running everything natively. See the dedicated Windows with WSL2 guide which covers Ubuntu setup, memory configuration, Docker, GitHub CLI, and network bridging to a Windows-hosted database.
The steps below use native Windows tooling (PowerShell / cmd) and remain a valid alternative.
Prerequisitesβ
1. Gitβ
Download the installer from git-scm.com/download/win. During setup choose "Git from the command line and also from 3rd-party software" when asked about PATH.
After installation, configure line endings to avoid CRLF issues in shell scripts:
git config --global core.autocrlf input
Verify: git --version
2. Node.js 26β
Download the Windows Installer (.msi) for Node.js 26 from nodejs.org/en/download. Run the installer with default settings.
After installation, open a new PowerShell or Command Prompt window so the updated PATH takes effect.
Verify: node --version β v24.x.x
3. Yarn 4.12.0β
corepack enable
corepack prepare [email protected] --activate
If you see this error when running yarn:
yarn.ps1 cannot be loaded because running scripts is disabled on this system.
This is a Windows PowerShell execution policy restriction. Fix it with a one-time user-scoped change:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Then retry corepack prepare [email protected] --activate.
Alternative: use Git Bash or Command Prompt (cmd.exe) instead of PowerShell β the execution policy restriction does not apply in those shells. All subsequent yarn commands in this guide work identically in cmd.exe or Git Bash.
Verify: yarn --version β 4.12.0
4. Visual Studio 2022 Build Toolsβ
Required for native Node.js add-ons. Open PowerShell as Administrator and run:
winget install Microsoft.VisualStudio.2022.BuildTools
winget install Microsoft.VCRedist.2015+.x64
If you prefer the graphical installer, make sure the "Desktop development with C++" workload is checked.
Automated one-time setup (optional)β
You can automate steps 3 and 4 by running the bundled helper script from an Administrator PowerShell:
.\scripts\setup-windows-dev.ps1
If Windows blocks the script (e.g. downloaded as part of a ZIP archive), unblock it first:
Unblock-File .\scripts\setup-windows-dev.ps1
The script validates and installs: WSL 2 defaults, Node.js 26, Yarn 4.12.0, Git PATH repair, VS 2022 Build Tools, and VC++ Redistributable. It does not install Docker Desktop, clone the repo, or run bootstrap commands.
Infrastructure servicesβ
PostgreSQL is the most critical dependency β the app runs with a native PostgreSQL instance even without the rest of the Docker stack. Choose one option:
Option A β Native PostgreSQL + pgAdmin (recommended)β
The official Windows installer from postgresql.org/download/windows bundles pgAdmin 4, a full-featured database GUI β no extra installation needed.
-
Download and run the EDB installer. Note the port (default
5432) and thepostgressuperuser password you set. -
Open pgAdmin 4 from the Start menu to browse and manage your databases visually.
-
Create the application database. In pgAdmin's Query Tool or PowerShell:
psql -U postgres -c "CREATE DATABASE \"saasframe\";" -
Set
DATABASE_URLinapps\saasframe\.env(after cloning):DATABASE_URL=postgres://postgres:<your-password>@localhost:5432/saasframe
For Redis and Meilisearch, start only those two services via Docker (requires Docker Desktop):
docker compose up -d redis meilisearch
Most development features work without Meilisearch β you can skip it and add it later.
Option B β Docker Desktop (all infrastructure)β
Install Docker Desktop for Windows with the WSL 2 backend enabled (Settings β General β "Use the WSL 2 based engine").
Start all infrastructure from the repository root:
docker compose up -d
Microsoft Defender exclusion (recommended)β
Without a Defender exclusion, yarn install and file-watching can be significantly slower. Run once in an elevated PowerShell:
Start-Process powershell -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"Add-MpPreference -ExclusionPath '$((Get-Location).Path)'`""
Clone and configureβ
git clone https://github.com/saasframe/saasframe.git
cd saasframe
git checkout develop
Copy the environment template:
Copy-Item apps\saasframe\.env.example apps\saasframe\.env
Edit apps\saasframe\.env and set at minimum:
DATABASE_URL=postgres://postgres:<password>@localhost:5432/saasframe
JWT_SECRET=change-me-dev-secret
REDIS_URL=redis://localhost:6379
Install dependencies and bootstrapβ
yarn install
yarn build:packages
yarn generate
yarn build:packages
yarn initialize
yarn build:packages must run twice β once before yarn generate and once after β so the generated scripts are compiled before yarn initialize runs.
The admin credentials are printed at the end of yarn initialize.
Start the appβ
yarn dev
Open http://localhost:3000/backend and sign in with the credentials printed by yarn initialize.
Ephemeral environment (optional β requires Docker Desktop)β
yarn dev:ephemeral spins up a throwaway database on a random free port and starts the app. Docker Desktop must be running:
yarn dev:ephemeral
Upgrading an existing checkoutβ
git pull
yarn install
yarn db:migrate
yarn generate
yarn dev
Development runtime referenceβ
| Command | Description |
|---|---|
yarn dev | Compact runtime β splash at http://localhost:4000, app at http://localhost:3000/backend |
yarn dev:verbose | Same runtime with raw passthrough logs |
yarn dev:greenfield | Full fresh boot: build β generate β reinstall β dev |
yarn dev:ephemeral | Throwaway database on a random port (requires Docker) |
yarn dev:classic | Legacy mode β disables splash, raw output |
Press d while yarn dev is running to toggle raw log output. If a stage fails, the runner automatically expands and prints the raw error.
Run multiple persistent local instances against the same PostgreSQL serverβ
yarn dev, yarn dev:greenfield, and yarn dev:app accept an optional --database-name[=<name>] flag that rewrites the database segment of DATABASE_URL in apps/saasframe/.env. Without the flag, behavior is unchanged.
# explicit name; you'll be asked once whether to persist .env (default yes)
yarn dev:greenfield --database-name=pricing_v2
# bare flag derives the database name from the current working directory
yarn dev --database-name
# one-off review run that does not edit .env
yarn dev --database-name=review_1720 --no-update-env
The override only touches the pathname segment of DATABASE_URL, so credentials, host, port, schema (?schema=β¦), and other query parameters are preserved. CI / non-interactive runs default to updating .env; pass --no-update-env to opt out, or set SF_DEV_DATABASE_UPDATE_ENV=false.