Skip to content

Development Guide

Generated: 2026-01-04

  • Node.js: ≥18 (check with node -v)
  • pnpm: 10.16.1+ (install with npm install -g pnpm)
  • Bun: 1.2+ (for whatsapp-web-server)
  • Docker: For local PostgreSQL
  • Git: Latest version
Terminal window
git clone https://github.com/your-org/NexisChat.git
cd NexisChat
Terminal window
pnpm install

This installs all workspace dependencies and links local packages.

Each app has its own .env file. Copy the examples:

Terminal window
# Server
cp apps/server/.env.example apps/server/.env
# Client
cp apps/client/.env.example apps/client/.env
# WhatsApp Web Server
cp apps/whatsapp-web-server/.env.example apps/whatsapp-web-server/.env

Start PostgreSQL with Docker:

Terminal window
cd apps/server
docker compose -f development.docker-compose.yml up -d

Run migrations:

Terminal window
pnpm --filter server db:push
# or
pnpm --filter server db:migrate
Terminal window
# All services (recommended)
pnpm dev
# Individual services
pnpm --filter client dev # :3000
pnpm --filter server dev # :8787
pnpm --filter whatsapp-web-server dev # :8788
pnpm --filter landing dev # :4321
pnpm --filter docs dev # :3002
CommandDescription
pnpm devStart all dev servers
pnpm buildBuild all packages
pnpm lintLint all packages
pnpm formatFormat all files
pnpm typecheckType-check all packages
pnpm testRun all tests
pnpm cleanRemove build artifacts
Terminal window
pnpm --filter client dev # Start dev server
pnpm --filter client build # Production build
pnpm --filter client preview # Preview production build
pnpm --filter client lint # Run ESLint
pnpm --filter client typecheck # Type-check
Terminal window
pnpm --filter server dev # Start dev server
pnpm --filter server build # Production build
pnpm --filter server test # Run tests
pnpm --filter server db:push # Push schema to DB
pnpm --filter server db:generate # Generate migration
pnpm --filter server db:migrate # Run migrations
pnpm --filter server db:studio # Open Drizzle Studio

WhatsApp Web Server (apps/whatsapp-web-server)

Section titled “WhatsApp Web Server (apps/whatsapp-web-server)”
Terminal window
pnpm --filter whatsapp-web-server dev # Start with Bun
pnpm --filter whatsapp-web-server build # Build
pnpm --filter whatsapp-web-server start # Production start
Terminal window
pnpm --filter ui storybook # Start Storybook
pnpm --filter ui build # Build component library
pnpm --filter ui test # Run component tests
pnpm --filter ui chromatic # Run visual regression
Terminal window
# Generate migration from schema changes
pnpm --filter server db:generate
# Apply migrations
pnpm --filter server db:migrate
# Push schema directly (dev only)
pnpm --filter server db:push
# Open Drizzle Studio (GUI)
pnpm --filter server db:studio
.env
DATABASE_URL=postgresql://user:password@localhost:5432/nexischat
Terminal window
# All tests
pnpm test
# Specific package
pnpm --filter server test
pnpm --filter ui test
# Watch mode
pnpm --filter server test:watch
# Coverage
pnpm --filter server test:coverage
Terminal window
# Start Storybook
pnpm --filter ui storybook
# Run Storybook tests
pnpm --filter ui test:storybook
# Visual regression (requires Chromatic token)
pnpm --filter ui chromatic
Terminal window
# Lint all
pnpm lint
# Lint specific package
pnpm --filter client lint
# Auto-fix
pnpm lint --fix
Terminal window
# Format all
pnpm format
# Check formatting
pnpm format:check
Terminal window
# All packages
pnpm typecheck
# Specific package
pnpm --filter server typecheck
Terminal window
# Add to client
pnpm --filter client add react-icons
# Add dev dependency
pnpm --filter server add -D vitest
# Add workspace dependency
pnpm --filter client add @nexischat/ui@workspace:*
Terminal window
pnpm add -D -w turbo
  1. Create component directory:
Terminal window
mkdir -p packages/ui/src/atoms/my-component
  1. Create component file:
packages/ui/src/atoms/my-component/my-component.tsx
import { cn } from '../../lib/utils'
interface MyComponentProps {
className?: string
children: React.ReactNode
}
export function MyComponent({ className, children }: MyComponentProps) {
return <div className={cn('base-styles', className)}>{children}</div>
}
  1. Create story:
packages/ui/src/atoms/my-component/my-component.stories.tsx
import type { Meta, StoryObj } from '@storybook/react'
import { MyComponent } from './my-component'
const meta: Meta<typeof MyComponent> = {
title: 'Atoms/MyComponent',
component: MyComponent
}
export default meta
type Story = StoryObj<typeof MyComponent>
export const Default: Story = {
args: {
children: 'Hello World'
}
}
  1. Export from index:
packages/ui/src/index.ts
export * from './atoms/my-component/my-component'
DATABASE_URL=postgresql://...
WORKOS_CLIENT_ID=...
WORKOS_API_KEY=...
WORKOS_REDIRECT_URI=...
BETTER_AUTH_SECRET=...
CREEM_API_KEY=...
VITE_SERVER_URL=http://localhost:8787
VITE_WORKOS_CLIENT_ID=...
VITE_SENTRY_DSN=...
DATABASE_URL=postgresql://...
WORKOS_CLIENT_ID=...
WORKOS_API_KEY=...
WAHA_API_KEY=...
Terminal window
# Clear caches and reinstall
pnpm clean
rm -rf node_modules
pnpm install
Terminal window
# Restart TS server in VS Code
Cmd+Shift+P "TypeScript: Restart TS Server"
# Or rebuild
pnpm build
Terminal window
# Check Docker is running
docker ps
# Restart database
cd apps/server
docker compose -f development.docker-compose.yml down
docker compose -f development.docker-compose.yml up -d
Terminal window
# Find process
lsof -i :3000
# Kill process
kill -9 <PID>

Recommended extensions (see .vscode/extensions.json):

  • ESLint
  • Prettier
  • Tailwind CSS IntelliSense
  • TypeScript Importer
  • Prisma (for Drizzle syntax highlighting)
{
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"typescript.preferences.importModuleSpecifier": "relative"
}
  • feature/description - New features
  • fix/description - Bug fixes
  • chore/description - Maintenance
  • docs/description - Documentation

Follow Conventional Commits:

feat: add user profile page
fix: resolve login redirect issue
chore: update dependencies
docs: add API documentation
  1. Create feature branch from main
  2. Make changes with atomic commits
  3. Run pnpm lint && pnpm typecheck && pnpm test
  4. Push and create PR
  5. Wait for CI checks
  6. Request review
  7. Squash merge when approved