| title | TSS Elysia |
|---|---|
| description | A full-stack TypeScript application using TanStack Start, Elysia, React 19, and Bun |
A full-stack TypeScript application using TanStack Start, Elysia, React 19, and Bun.
Project Roadmap: See PLANS.md for detailed feature planning and progress tracking.
bun install
bun run devRun once after cloning the project to set up everything:
bun run setupWhat it does:
- Checks Bun runtime is installed
- Installs project dependencies
- Creates
.envfrom.env.example - Generates database schema and runs migrations
- Seeds the database with initial data
- Sets up git hooks
- Runs typecheck to verify setup
Options:
--skip-db- Skip database setup (if you want to set it up manually)
Clean up build artifacts, test results, and temporary files:
bun run cleanupOptions:
--dry-run- Show what would be deleted without actually deleting--keep-db- Preserve database files (.artifacts/*.db)--full- Full reset includingnode_modules(rarely needed)
Note: Executable files like
k6.exein.artifacts/are automatically preserved during cleanup. Before load test make sure to run vite previewbun run preview
Detailed documentation available in docs/:
| Document | Description |
|---|---|
| API Reference | API endpoints and usage |
| Architecture | System architecture overview |
| Authentication | Auth setup and configuration |
| CI/CD | CI/CD pipelines and releases |
| Development | Development guide |
| Docker | Docker deployment guide |
| Environment Variables | Environment configuration |
| Middleware | Middleware documentation |
| Overview | Project introduction |
| Testing | Testing guide |
| Tools Reference | Core tools and technologies |
| Troubleshooting | Common issues and solutions |
- Framework: TanStack Start
- Server: Elysia
- Runtime: Bun
- UI: React 19 + TypeScript
- Form: tanstack-form
- Table: TanStack Table v8
- State Management: TanStack Store
- Function Execution Timing: TanStack Pacer
- Styling: Tailwind CSS v4
- Logging: Evlog with structured logging and multiple adapters (FS, OTLP)
- Cache: Unstorage with multi-backend support
- Redis (when
REDIS_URLis set) - PostgreSQL (when
DATABASE_TYPE=postgres) - LRU Cache (default for SQLite)
- Redis (when
- Pub/Sub: Unstorage-based with multi-backend support (Redis recommended for cross-instance)
The API follows a layered architecture pattern (HTTP → Controller → Service → Repository):
The dashboard API demonstrates the layered architecture pattern:
- HTTP Layer:
src/routes/api/dashboard/-metrics.ts(route definitions, HTTP handling) - Controller Layer: Not used for dashboard (business logic in service)
- Service Layer:
src/services/dashboard/dashboard.service.ts(fetches from API endpoints) - Repository Layer: Not used for dashboard (service calls HTTP APIs directly)
For dashboard-specific data, the service layer makes HTTP requests to the dashboard API endpoints rather than accessing a repository directly, since the data comes from various microservices and analytics platforms.
┌─────────────────────────────────────────────────────────────┐
│ HTTP Layer (routes/) │
│ - Elysia route definitions │
│ - Request/Response handling │
│ - OpenAPI documentation │
│ - Delegates to controllers │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Controller Layer (controllers/) │
│ - Session validation │
│ - Request parsing and validation │
│ - Response formatting │
│ - HTTP-specific logic │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Service Layer (services/) │
│ - Business logic │
│ - Data transformation │
│ - Validation rules │
│ - Orchestrates repositories │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Repository Layer (repositories/) │
│ - ORM operations (Drizzle) │
│ - Database queries │
│ - Data access abstraction │
│ - Interface-based design │
└──────────────────────┬──────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Database (SQLite/PostgreSQL) │
└─────────────────────────────────────────────────────────────┘| Layer | Directory | Responsibility |
|---|---|---|
| HTTP | src/routes/api/ |
Route definitions, HTTP handling, OpenAPI docs |
| Controller | src/controllers/ |
Session validation, request parsing, response formatting |
| Service | src/services/ |
Business logic, data transformation, validation |
| Repository | src/repositories/ |
ORM operations, database queries, data access |
Repositories support dependency injection via constructor for testability:
// Repository with optional db parameter
export class AccountRepository implements IAccountRepository {
private db: DbType;
constructor(db?: DbType) {
this.db = db ?? defaultDb;
}
async findAccountByUserId(userId: string) {
return Result.tryPromise({
try: () => this.db.select()..., // Uses injected db
catch: (error) => new DatabaseError(...),
});
}
}
// In tests: inject mock database
const mockDb = {
select: () => ({ from: () => ({ where: () => ({ limit: () => Promise.resolve([]) }) }) ),
// ...
};
const repository = new AccountRepository(mockDb);This enables:
- Inline mocking without actual database connections
- Unit tests that run fast and reliably
- Isolation from infrastructure concerns
Request → routes/api/settings/-profile.ts (HTTP)
↓
controllers/settings/controller.ts (session validation)
↓
services/dashboard/settings/profile.ts (business logic)
↓
repositories/settings/profile.repository.ts (ORM query)
↓
Databasesrc/
├── assets/ # Static assets and icons
│ ├── auth-banner-dark.png
│ ├── auth-banner-light.png
│ ├── brand-icons/ # Brand icons (Facebook, GitHub, Gmail)
│ ├── custom/ # Custom icons (layout, sidebar, theme)
│ ├── shared/ # Shared icon base component
│ └── logo.tsx
├── components/ # React components
│ ├── ui/ # shadcn/ui components (30+ components)
│ │ ├── accordion.tsx
│ │ ├── alert-dialog.tsx
│ │ ├── button.tsx
│ │ ├── card.tsx
│ │ ├── table.tsx
│ │ ├── tooltip.tsx
│ │ └── error-display.tsx # Reusable error display
│ ├── data-table/ # TanStack Table components
│ │ ├── index.ts
│ │ ├── pagination.tsx
│ │ ├── column-header.tsx
│ │ ├── toolbar.tsx
│ │ └── view-options.tsx
│ ├── auth/ # Auth components (simplified)
│ │ └── auth-guard.tsx
│ ├── docs/ # Documentation components
│ │ ├── sidebar.tsx
│ │ ├── markdown.tsx
│ │ └── code-highlight.tsx
│ ├── layout/ # Layout components
│ │ ├── app-sidebar.tsx
│ │ ├── header.tsx
│ │ ├── landing/ # Landing page components
│ │ └── types.ts
│ ├── settings/ # Settings components
│ ├── profile/ # Profile components
│ ├── theme/ # Theme components
│ └── shared/ # Shared components (multi-delete-dialog, etc.)
├── config/ # Central configuration
│ ├── index.ts # Main config exports
│ ├── auth.ts # Better Auth configuration
│ ├── db/ # Database config (heartbeat, index)
│ ├── docs.ts # Documentation config
│ ├── env.ts # Environment validation
│ ├── evlog.ts # Evlog configuration
│ └── features.tsx # Shared features config
├── context/ # React context providers
│ ├── direction-provider.tsx
│ ├── font-provider.tsx
│ ├── layout-provider.tsx
│ ├── search-provider.tsx
│ └── theme-provider.tsx
├── controllers/ # Controller layer (HTTP-specific logic)
│ ├── mcp/ # MCP controllers
│ ├── settings/ # Settings controllers
│ └── index.ts
├── features/ # Feature modules (components, pages, data)
│ ├── apps/ # Apps feature
│ ├── auth/ # Auth feature (sign-in, sign-up, OTP, forgot-password)
│ │ ├── shared/ # Shared auth components (email-field, social-sign-in)
│ │ └── components/
│ ├── chats/ # Chats feature
│ ├── dashboard/ # Dashboard feature
│ ├── errors/ # Error pages (401, 403, 404, 500, 503)
│ ├── landing/ # Landing pages (blog, changelog, docs, status)
│ ├── settings/ # Settings feature (account, appearance, profile, notifications)
│ ├── tasks/ # Task management feature
│ └── users/ # User management feature
├── hooks/ # Custom React hooks
│ ├── use-dialog-state.tsx
│ ├── use-mobile.tsx
│ ├── use-scroll-direction.tsx
│ └── use-table-url-state.ts
├── lib/ # Library code
│ ├── auth/ # Authentication (Better Auth)
│ │ ├── index.ts # Server auth instance
│ │ ├── client.ts # Client auth hooks
│ │ └── dashboard/ # Dashboard auth utilities
│ ├── cache/ # Cache layer (Unstorage-backed)
│ ├── db/ # Database (Drizzle + SQLite/PostgreSQL)
│ │ ├── schema/ # DB schemas (auth, mcp, subscriptions, user-settings)
│ │ └── schema.ts
│ ├── mcp/ # MCP (Model Context Protocol)
│ │ ├── tools/ # MCP tools (auth, users, organizations, shared-utils)
│ │ ├── shared/ # Shared MCP utilities (auth-utils, response-helpers)
│ │ └── server.ts
│ ├── stores/ # TanStack Stores
│ └── dashboard/ # Dashboard utilities (CSRF, rate-limit, sanitizer)
├── middlewares/ # Middleware implementations
│ ├── cors.ts
│ ├── helmet.ts
│ ├── rate-limit.ts
│ └── index.ts
├── plugins/ # Vite/Plugin configurations
│ ├── evlog-plugin.ts
│ ├── monitoring.ts
│ └── websocket.ts
├── repositories/ # Repository layer (ORM operations)
│ ├── mcp/ # MCP repositories
│ ├── settings/ # Settings repositories
│ └── index.ts
├── services/ # Service layer (business logic)
│ ├── settings/ # Settings services (profile, account, display, notifications)
│ ├── llmo/ # LLM optimization services (blog, docs, changelog, FAQ)
│ ├── mcp/ # MCP services (api-keys, tools, rate-limiter)
│ └── status/ # Status services (history)
├── routes/ # File-based routing (TanStack Start)
│ ├── (auth)/ # Auth routes (sign-in, sign-up, OTP, forgot-password, verify-email)
│ ├── (errors)/ # Error pages (401, 403, 404, 500, 503)
│ ├── (landing)/ # Landing routes (blog, changelog, docs, status, privacy, terms)
│ ├── _authenticated/ # Protected routes (dashboard, tasks, users, chats, settings)
│ ├── api/ # API routes (HTTP Layer)
│ │ ├── auth/ # Auth API routes
│ │ ├── mcp/ # MCP API routes
│ │ ├── root/ # Core API routes (cache, database, llmo, realtime, status)
│ │ └── settings/ # Settings API routes
│ ├── __root.tsx # Root route
│ └── index.tsx # Home route
├── server.ts # TanStack Start server entry
├── router.tsx # TanStack Router configuration
├── routeTree.gen.ts # Auto-generated route tree
├── types/ # TypeScript type definitions
└── styles/ # Global styles
└── app.css # Tailwind CSS v4 importstest/ # Unit & component tests (Bun)
├── components/ # Component & hook tests
│ ├── auth/ # Auth component tests
│ ├── context/ # React context tests
│ ├── dashboard/ # Dashboard component tests
│ ├── hooks/ # Custom hook tests
│ └── ui/ # UI component tests
├── fixtures/ # Test fixtures & factories
│ ├── db.ts
│ ├── tokens.ts
│ └── users.ts
├── helpers/ # Test helpers (app, auth, request)
├── scripts/ # Script tests (CLI, decisions, tasks)
├── setup.ts # Test setup/global preload
├── types/ # Type tests
└── unit/ # Unit tests
├── config/ # Configuration tests
├── contract/ # Contract tests (Eden Treaty)
│ ├── api/ # API endpoint contract tests
│ │ ├── auth/
│ │ ├── dashboard/
│ │ ├── mcp/
│ │ ├── roles/
│ │ ├── settings/
│ │ └── users/
│ └── openapi/ # OpenAPI spec contract tests
├── features/ # Feature tests
├── lib/ # Library tests
│ ├── auth/
│ ├── cache/
│ ├── config/
│ ├── dashboard/
│ ├── db/
│ ├── docker/
│ ├── mcp/
│ │ └── tools/
│ ├── pagination/
│ ├── rate-limit/
│ ├── realtime/
│ └── store/
├── middlewares/ # Middleware tests
├── plugins/ # Plugin tests
├── repositories/ # Repository tests
├── routes/ # Route tests
├── services/ # Service layer tests
│ └── dashboard/
├── types/ # Type utility tests
├── utils/ # Utility function tests
└── validators/ # Validator tests
.e2e/ # E2E tests (Playwright)
├── components/ # Component E2E tests
│ ├── branding.spec.ts
│ └── dashboard.spec.ts
├── lib/ # Library E2E tests
│ └── auth.spec.ts
├── middlewares/ # Middleware E2E tests
│ ├── cors.spec.ts
│ ├── error-handling.spec.ts
│ ├── helmet.spec.ts
│ ├── rate-limit.spec.ts
│ └── trace.spec.ts
├── realtime/ # WebSocket E2E tests
│ └── websocket.spec.ts
├── routes/ # Route E2E tests
│ ├── (auth)/ # Auth flow E2E tests
│ ├── (errors)/ # Error page E2E tests
│ ├── _authenticate/ # Protected route E2E tests
│ │ └── dashboard/
│ ├── blog.spec.ts
│ ├── cache.spec.ts
│ ├── changelog.spec.ts
│ ├── docs.spec.ts
│ ├── llmo.spec.ts
│ ├── permissions.spec.ts
│ ├── protected-route.spec.ts
│ └── status.spec.ts
├── ui/ # UI component E2E tests
├── auth.spec.ts # Auth flow tests
├── landing.spec.ts # Landing page tests
├── mobile.spec.ts # Mobile responsiveness tests
├── navigation.spec.ts # Navigation tests
├── _setup.ts # Global setup
├── _teardown.ts # Global teardown
├── config.ts # E2E configuration
└── utils.ts # E2E utilities
.k6/ # Load tests (k6)
├── api-test.js
├── smoke-test.js
└── stress-test.js- Use oxfmt for code formatting (configured in
.oxfmtrc.json) - Run
bun run formatbefore committing
- Uses oxlint with plugins:
unicorn,typescript,oxc - Configuration in
.oxlintrc.json
- Path alias:
~/*maps to./src/* - JSX mode:
react-jsx
- Components: PascalCase (e.g.,
RootDocument) - Files: kebab-case for routes (e.g.,
__root.tsx) - Utilities: camelCase (e.g.,
getRouter()) - Constants: SCREAMING_SNAKE_CASE`
- Use path alias
~/*for src imports (e.g.,import appCss from "~/styles/app.css?url") - CSS imports require
?urlsuffix for Vite`
- Functional components with TypeScript
- Use
createRootRoute,createRoutefrom@tanstack/react-router - Use
<Link>for navigation,<HeadContent />,<Scripts />in root layout - Include
<TanStackRouterDevtools>in development (bottom-right)
- Use
defaultErrorComponentanddefaultNotFoundComponentin router config - Return proper HTTP status codes in server handlers`
- Tailwind CSS v4 with Vite plugin
- Import with
@import "tailwindcss";inapp.css
- Uses Zod v4 for runtime validation
- Prefer Zod schemas over custom validation logic`
-
Pre-commit hooks run:
lint,typecheck,react:doctor -
Use changelogen for version management (conventional commits):
# Make conventional commits (feat:, fix:, etc.) bun changelogen # Generate changelog bun changelogen --bump # Bump version bun changelogen gh release # Create GitHub release
For more detailed troubleshooting guide, see Troubleshooting.
Common issues:
- If imports fail, ensure
bun installhas run` - Path alias
~/*requires TypeScript paths configuration` - CSS files must use
?urlsuffix for Vite's asset handling`
For detailed agent coding guidelines, see AGENTS.md.
For feature planning and progress tracking, see PLANS.md.