An opinionated, full-stack monorepo built for performance, type-safety, and an unparalleled developer experience.
Powered by Elysia, Astro, and React.
The EAR Stack is more than just a template; it's a foundation for building robust, modern web applications without compromising on performance or developer sanity. It was born from the desire to integrate best-in-class tools into a cohesive, scalable, and delightful-to-use monorepo.
-
β End-to-End Type Safety: We believe type safety is non-negotiable. By leveraging TypeScript across the entire stack and using Elysia's Eden client, you get auto-completion and compile-time checks from your database schema all the way to your React components.
-
β‘ Performance by Default: This stack is built for speed. Bun provides a lightning-fast runtime and toolkit. Elysia is one of the fastest backend frameworks available. And Astro ships zero JavaScript by default, ensuring optimal load times for your content-driven sites.
-
π¦ Seamless Scalability: The monorepo is managed with Nx, which provides an extensible build system, intelligent caching, and a clear structure that grows with your project. Shared packages ensure code is reusable and consistent across all applications.
-
π¨ Universal Component-Driven UI: The shared
packages/uilibrary is being ported to Tamagui, enabling you to write components once and run them on both web and native platforms. This, combined with Tailwind CSS, provides a powerful and consistent design system. -
π§ Exceptional Developer Experience: From the moment you clone the repository, you're set up for success. Pre-configured tooling for linting, formatting, git hooks, and CI/CD means you can focus on building features, not on boilerplate.
This project brings together a best-in-class set of technologies, each chosen for their strengths and seamless integration into a unified developer experience.
| Technology | Purpose & Strengths | Location |
|---|---|---|
| Bun | Ultra-fast JS/TS runtime, package manager, and bundler | Root |
| Nx | Powerful monorepo management, caching, and task orchestration | Root |
| Elysia | Blazing-fast, type-safe backend API framework | apps/server |
| Drizzle ORM | End-to-end type safety for SQL databases | apps/server |
| Astro | Content-focused web framework, ships zero JS by default | apps/* |
| React | Industry-standard UI library for dynamic, interactive apps | apps/* |
| TanStack Start | Modern full-stack React framework (routing, data, auth) | apps/dashboard |
| Expo | Universal React Native app framework for web & native | apps/native |
| TypeScript | Strict type safety across the full stack | Everywhere |
| Tailwind CSS | Rapid, utility-first CSS for consistent design | packages/ui |
| Tamagui | Universal UI kit for React Native & Web (WIP) | packages/ui, config |
| Biome | Lint, format, and code quality toolβall-in-one, fast | Everywhere |
| Husky | Git hooks for enforcing code standards before commits | .husky/ |
| GitHub Actions | Automated CI: linting, type-checks & more | .github/workflows |
The repository is organized into apps and packages, a standard and effective monorepo strategy. This structure promotes code sharing and clear separation of concerns.
.
βββ apps/
β βββ blog/ # π Astro-powered blog. Consumes `packages/ui`.
β βββ dashboard/ # π Dynamic React dashboard. Consumes `packages/ui` & `packages/eden`.
β βββ docs/ # π Documentation site with Astro Starlight. Consumes `packages/ui`.
β βββ landing-page/ # π Marketing page built with Astro. Consumes `packages/ui`.
β βββ native/ # π± Expo (React Native) app. Will consume `packages/ui` (Tamagui).
β βββ server/ # βοΈ Elysia backend. Exposes a type-safe API for other apps.
β βββ storybook/ # π¨ (WIP) Component development environment for `packages/ui`.
β
βββ packages/
β βββ brand/ # π¨ Shared branding assets and design tokens.
β βββ config/ # βοΈ (WIP) Shared configuration for Tamagui.
β βββ eden/ # π Type-safe Eden client generated from the `server`'s API.
β βββ ui/ # π§© (WIP) Shared UI library, being ported to Tamagui.
β
βββ tooling/
βββ typescript/ # π οΈ Centralized TypeScript configurations (base, react, astro, etc.).
Follow these steps to get your local development environment up and running.
- Node.js (v20+ is recommended for compatibility with some ecosystem tools).
- Bun (v1.0 or higher). Bun will be used as the package manager and runtime.
git clone https://github.com/Yorizel/ear-monorepo.git
cd ear-monorepoThis project uses Bun Workspaces. The bun install command will install dependencies for all apps and packages in the monorepo.
bun installYou need to set up environment variables for the applications that require them.
- Backend Server (
apps/server):cp apps/server/.env.example apps/server/.env
- Dashboard (
apps/dashboard):cp apps/dashboard/.env.example apps/dashboard/.env
After copying, edit the .env files and provide the necessary values. You will need:
- A PostgreSQL
DATABASE_URL. A free tier from Neon is a great option. - A secret string for
BETTER_AUTH_SECRET. You can generate one withopenssl rand -hex 32.
Push the Drizzle ORM schema to your PostgreSQL database. This command reads your schema files and applies the necessary changes to your database.
bun run --filter server db:pushStart all applications concurrently using the root dev:all script.
bun run dev:allThis command leverages Nx to run the dev script for each application in parallel. You can access them at their respective default ports:
- Landing Page:
http://localhost:4321 - Dashboard:
http://localhost:3000 - Blog:
http://localhost:4322 - Docs:
http://localhost:4323 - Server:
http://localhost:9876
Key scripts are defined in the root package.json and can be run with bun run <script-name>.
| Script | Description |
|---|---|
build |
Build all applications and packages for production using Nx. |
check |
Run Biome linter across all projects. |
format |
Format all code in the repository using Biome. |
typecheck |
Run TypeScript compiler checks across all projects. |
dev:all |
Start all applications in development mode. |
dev:dashboard |
Start only the server, dashboard, and native apps. |
dev:content-apps |
Start only the docs, blog, and landing-page apps for content editing. |
To run scripts for a specific app or package, use the bun run --filter <workspace> <script> command.
| Command | Description |
|---|---|
bun run --filter server db:generate |
Generate a new Drizzle database migration file based on schema changes. |
bun run --filter server db:push |
Push the current schema to the database (ideal for development). |
bun run --filter server auth:generate |
Generate the auth schema based on the auth config. |
This project uses Biome as an all-in-one tool for linting and formatting, which ensures code quality and a consistent style. A pre-commit hook is configured with Husky to automatically format your staged files, so you never have to worry about style inconsistencies.
We enforce Conventional Commits using commitlint. This standard creates a clean, readable, and automated git history, which is crucial for changelog generation and versioning. When you commit, your message will be validated.
The repository is equipped with GitHub Actions workflows found in .github/workflows. On every pull request, these workflows automatically:
check.yml: Runbun run checkto ensure all code passes Biome's linter.typecheck.yml: Runbun run typecheckto verify the project is free of TypeScript errors.
We welcome contributions! If you have suggestions for improvements or find a bug, please feel free to open an issue or submit a pull request.
When contributing, please ensure your code adheres to the project's formatting and commit conventions.
This project is licensed under the MIT License. See the LICENSE.md file for details.