Skip to content

Local Development

This guide walks you through setting up your local development environment to contribute to the Sayr codebase.

Before you begin, ensure you have the following tools installed:

ToolVersionPurpose
Node.js22+ (LTS recommended)Runtime for frontend and tooling
Bun1.0+Runtime for backend and worker services
pnpm10.6+Package manager
PostgreSQL15+Primary database
DockerLatest (optional)Containerized development
Terminal window
# Install pnpm globally
npm install -g pnpm
# Install Bun (required for backend/worker)
curl -fsSL https://bun.sh/install | bash
# Verify installations
node --version # Should be 22+
pnpm --version # Should be 10.6+
bun --version # Should be 1.0+

Sayr is a Turborepo monorepo with the following structure:

sayr/
├── apps/
│ ├── backend/ # Hono API server (Bun, port 5468)
│ ├── start/ # TanStack Start frontend (port 3000)
│ ├── marketing/ # Astro docs/marketing site (port 3002)
│ └── worker/ # GitHub webhook processor (Bun)
├── packages/
│ ├── auth/ # Better Auth configuration
│ ├── database/ # Drizzle ORM schemas and CRUD
│ ├── storage/ # MinIO S3-compatible client
│ ├── ui/ # Shadcn/ui component library
│ ├── util/ # Shared utilities
│ ├── queue/ # Job queue abstraction
│ └── opentelemetry/ # Tracing utilities
└── ...
Terminal window
git clone https://github.com/dorasto/sayr.git
cd sayr

We recommend using pnpm for all package management tasks:

Terminal window
pnpm install

Copy the environment template to each app that requires it:

Terminal window
cp .env.example apps/backend/.env
cp .env.example apps/start/.env
cp .env.example apps/worker/.env

Edit each .env file with your local configuration. Key variables include:

Database:

DATABASE_URL=postgresql://user:password@localhost:5432/sayr

Storage (MinIO/S3):

STORAGE_URL=http://localhost:9000
STORAGE_BUCKET=sayr
STORAGE_ACCESS_KEY=minioadmin
STORAGE_SECRET_KEY=minioadmin
FILE_SALT=your-random-salt
FILE_CDN=http://localhost:9000/sayr

Frontend:

VITE_URL_ROOT=http://admin.app.localhost:3000
VITE_PROJECT_NAME=Sayr
VITE_ROOT_DOMAIN=app.localhost

Ensure PostgreSQL is running, then push the schema:

Terminal window
pnpm -F @repo/database db:push

To explore your database with a visual interface:

Terminal window
pnpm -F @repo/database db:studio

Start all apps simultaneously:

Terminal window
pnpm dev

Or start specific apps:

Terminal window
# Backend API only
pnpm -F backend dev
# Frontend only
pnpm -F start dev
# Marketing/docs site only
pnpm -F marketing dev

Sayr uses subdomain-based routing in development. The primary reason behind this is due to constraints with how cookies are handled in development environments. By using subdomains, we can ensure that cookies are scoped to the correct domain, allowing for seamless authentication and session management.

URLPurpose
http://admin.app.localhost:3000Admin dashboard
http://{org-slug}.app.localhost:3000Organization workspace
http://localhost:5468Backend API
http://localhost:3002Marketing site and documentation (what you’re looking at right now)
CommandDescription
pnpm devStart all apps in development mode
pnpm buildBuild all apps for production
pnpm lintRun Biome linting
pnpm lint:fixFix linting issues automatically
pnpm check-typesRun TypeScript type checking
CommandDescription
pnpm -F @repo/database db:pushApply schema changes
pnpm -F @repo/database db:studioOpen Drizzle Studio
CommandDescription
pnpm -F start testRun all tests
pnpm -F start test -- --testNamePattern="pattern"Run tests matching pattern
pnpm -F start test -- path/to/file.test.tsRun specific test file

Sayr uses Biome for linting and formatting. Always run linting before committing:

Terminal window
pnpm lint # Check for issues
pnpm lint:fix # Auto-fix issues

For detailed coding conventions including import organization, naming conventions, error handling patterns, and component structure, see the Code Style Guide.

Sayr uses Shadcn/ui for the component library. To add a new component:

Terminal window
pnpm dlx shadcn@latest add <component-name>

If a port is already in use, you can find and kill the process:

Terminal window
# Find process using port 3000
lsof -i :3000
# Kill the process
kill -9 <PID>

Ensure PostgreSQL is running and the DATABASE_URL in your .env file is correct:

Terminal window
# Check PostgreSQL status
pg_isready -h localhost -p 5432

If you get “bun: command not found” errors, ensure Bun is installed system-wide and in your PATH:

Terminal window
# Check Bun installation
which bun
bun --version
# If not found, reinstall
curl -fsSL https://bun.sh/install | bash
source ~/.bashrc # or ~/.zshrc

After modifying database schemas, regenerate types:

Terminal window
pnpm -F @repo/database db:push

Once your environment is set up, explore these guides to learn more:

  1. Pick an issue from the GitHub Issues
  2. Create a feature branch from main
  3. Make your changes following our code style guidelines
  4. Run pnpm lint and pnpm check-types before committing
  5. Submit a pull request following our PR guidelines

Thank you for contributing to Sayr!