A modern API template built with Elysia.js, featuring authentication, database integration, and development tooling.
This project uses Bun as the runtime and package manager for fast development and execution.
Install dependencies:
bun installCopy the environment variables file:
cp .env.example .envTo run a PostgreSQL database using Docker:
docker run --name geut-api-db -e POSTGRES_DB=geut-api -e POSTGRES_USER=geut-api -e POSTGRES_PASSWORD=geut-api -p 5432:5432 -d postgres:latestUpdate the .env file with the database URL:
DATABASE_URL=postgresql://geut-api:geut-api@localhost:5432/geut-api
Then, generate and run migrations:
bun run db:generate
bun run db:migrateStart the development server:
bun run index.tsThe server will be available at http://localhost:3000.
bun run lint- Run the linter (Oxlint)bun run format- Format code with Oxfmtbun run lint:fix- Run linter with auto-fixbun run db:generate- Generate database migrationsbun run db:migrate- Run database migrations
This project uses Better Auth for authentication, integrated with Elysia.js through a custom plugin.
The auth configuration (src/auth.ts) includes:
- Database Adapter: Drizzle ORM with PostgreSQL
- Authentication Methods: Email and password signup/signin enabled
- Plugins: OpenAPI for API documentation generation
- Base Path: All auth routes are prefixed with
/auth
A custom Elysia plugin (src/plugins/better-auth.ts) mounts Better Auth's handler and provides an auth macro for route protection:
// Protected route example
.get('/user', ({ user }) => user, {
auth: true, // Requires authentication
})The plugin automatically resolves user sessions and provides user and session objects in route handlers.
GET/POST /auth/*- All Better Auth endpoints (signup, signin, session management)- Authentication routes are auto-generated and documented via OpenAPI
- Better Auth - Modern authentication library with email/password support
- Drizzle ORM - Type-safe SQL query builder
- PostgreSQL - Primary database
- Drizzle Kit - Migration and schema management
- Oxlint - Fast JavaScript/TypeScript linter
- Oxfmt - Fast JavaScript/TypeScript formatter
- Husky - Git hooks
- lint-staged - Run linters on staged files
- @elysiajs/cors - CORS middleware
- @elysiajs/openapi - OpenAPI documentation
- Path Aliases:
@/maps tosrc/directory - Editor Config: Consistent coding style across editors
- Pre-commit Hooks: Automatic linting and formatting on commits
├── src/
│ ├── auth.ts # Better Auth configuration
│ ├── plugins/
│ │ └── better-auth.ts # Elysia plugin for Better Auth integration
│ └── db/
│ ├── db.ts # Database connection
│ └── schema.ts # Drizzle schema
├── .vscode/ # VSCode settings
├── .husky/ # Git hooks
├── drizzle/ # Database migrations
├── index.ts # Main server file
├── tsconfig.json # TypeScript configuration
├── package.json # Dependencies and scripts
└── .env.example # Environment variables template
- Follow the established code style (enforced by Oxlint and Oxfmt)
- Use path aliases (
@/) for imports - Run migrations after schema changes
- Commit messages should be descriptive
This project was bootstrapped with bun init in Bun v1.3.5.