Building a Full-Stack TypeScript Application with Onion Architecture

Just set up the Effect Coffee Shop — one of the most impressive full-stack TypeScript projects I've explored. Here's my complete walkthrough.

📋 Metadata

Title: Building a Full-Stack TypeScript Application with Onion Architecture
Excerpt: A deep dive into building a production-grade full-stack TypeScript application using Bun, React, and the Effect library, demonstrating clean architecture patterns and AI integration.

Categories:

  • TypeScript
  • Full-Stack Development
  • Software Architecture
  • Functional Programming
  • AI/ML

Tags:

  • TypeScript 7.0
  • Bun
  • React
  • Effect Library
  • Onion Architecture
  • MCP
  • Full-Stack
  • Monorepo
  • AI Assistant
  • Functional Programming

Featured Image: (Add a screenshot of the running application UI with the coffee shop interface)


📝 Full Blog Post


Introduction: Beyond the “Todo App” Full-Stack Demo

When developers want to demonstrate full-stack capabilities, they often build a todo app. It’s simple, familiar, and gets the job done. But what happens when you want to show something more complex? Something that demonstrates real architectural patterns, production-ready code, and cutting-edge TypeScript features?

Enter the Effect Coffee Shop — an open-source reference application that pushes TypeScript to its limits while remaining approachable enough to learn from. This project showcases how to build a complete full-stack application using modern tools and architectural patterns that you’d actually use in production.

In this post, I’ll walk you through my journey of setting up and running this application on Debian, explaining each step along the way and highlighting the architectural decisions that make this project special.


Why This Project Matters

Before diving into the setup, let’s understand why the Effect Coffee Shop is worth your time:

1. Real-World Architecture

This isn’t a toy example. It implements Onion Architecture with clear separation of concerns, making the application testable, maintainable, and scalable.

2. Functional Programming with Effect

The project uses the Effect library, a powerful Type-first functional effect system that makes complex applications easier to reason about and debug.

3. True Full-Stack TypeScript

From the database layer to the React frontend, everything is written in TypeScript with strict type safety.

4. Multiple Interfaces, Same Logic

The same core business logic powers three different presentation layers:

  • HTTP REST API
  • Command-line interface (CLI)
  • MCP (Model Context Protocol) server for AI integration

5. AI Integration

The application includes an on-device AI assistant running Hugging Face Transformers — no API keys required!

6. Modern Tooling

It uses Bun for lightning-fast package management and runtime, Vite for the frontend build, and Turborepo for monorepo management.


Prerequisites: What You Need to Get Started

Before we begin the setup, make sure you have the following installed:

ToolMinimum VersionPurpose
Node.jsv22+JavaScript runtime
Bunv1.3.11+Package manager and runtime
GitLatestVersion control
A code editorVS Code recommendedDevelopment

Check your current versions:

bash

node --version
# Should output v22.22.3 or higher

bun --version
# Should output 1.4.0 or higher (you can use 1.3.11+)

Step 1: Installing Bun

The project uses Bun as both the package manager and JavaScript runtime. If you don’t have it installed, let’s get it set up.

Install Bun on Debian/Linux:

bash

curl -fsSL https://bun.sh/install | bash

Verify the installation:

bash

bun --version
# Expected output: 1.4.0 or higher

Why Bun? Bun is significantly faster than npm/yarn for package installation and provides an integrated JavaScript runtime similar to Node.js. It makes working with monorepos much smoother.


Step 2: Cloning the Repository

Now let’s get the source code:

bash

git clone https://github.com/kevinmichaelchen/effect-coffee-shop.git
cd effect-coffee-shop

Project Structure Overview:

text

effect-coffee-shop/
├── apps/
│   ├── backend/     # HTTP API server
│   └── web/         # React frontend
├── packages/
│   └── coffee/      # Shared business logic
│       ├── core/           # Domain logic
│       ├── external/       # Adapters (DB, services)
│       ├── presentation/   # HTTP, CLI, MCP handlers
│       └── runtime/        # Bun, Cloudflare, AWS
├── package.json     # Root dependencies
├── turbo.json       # Turborepo configuration
└── README.md        # Project documentation

Step 3: Installing Dependencies

This is where Bun’s speed really shines. Install all dependencies across the monorepo with a single command:

bash

bun install

What this does:

  • Installs root-level dependencies
  • Installs dependencies for all workspaces (backendwebpackages/*)
  • Creates node_modules folders where needed
  • Generates a bun.lock file for deterministic installs

Expected output:

  • node_modules folder in the root directory
  • Workspace dependencies installed
  • Around 2-3 minutes for a fresh install

Step 4: Running the Application

Now for the exciting part — getting everything up and running!

Start the development server:

bash

bun run dev

What happens under the hood:

  1. Turborepo identifies the packages to run
  2. The backend server starts on port 3000 (HTTP API)
  3. The frontend dev server starts on port 5173 (React/Vite UI)

Common Issue: Port 3000 Already in Use

You might encounter this error:

text

error: Failed to start server. Is port 3000 in use?

This happens when: Another process is already using port 3000.

How to fix it:

  1. Find the process using port 3000:

bash

sudo lsof -i :3000

Output example:

text

COMMAND    PID   USER FD   TYPE  DEVICE SIZE/OFF NODE NAME
bun     273404 lvydvy 7u  IPv6 4098508      0t0  TCP *:3000 (LISTEN)
  1. Kill the process:

bash

sudo kill -9 273404  # Replace 273404 with your PID
  1. Restart the dev server:

bash

bun run dev

Alternative solution: Run on a different port:

bash

COFFEE_HTTP_PORT=3001 bun run dev

Step 5: Exploring the Application

Once the dev server is running, you can access:

🌐 Web Interface

  • URL: http://localhost:5173
  • A React-based UI with a chat interface for the AI assistant
  • Interact with the coffee shop using natural language

📡 HTTP API

  • URL: http://localhost:3000
  • RESTful API endpoints for the coffee shop
  • Can be tested with tools like curl or Postman

🖥️ CLI Tool

Run commands directly from your terminal:

bash

# List the menu
bun run cli -- menu list

# Place an order
bun run cli -- order create --customer-name "Maya" --drink latte --size medium --milk oat --shots 2

# List all orders
bun run cli -- order list

# Get specific order details
bun run cli -- order get --order-id order-1

# Barista workflow
bun run cli -- barista start --order-id order-1
bun run cli -- barista ready --order-id order-1
bun run cli -- barista pickup --order-id order-1

🎯 The AI Assistant: Interacting with Beonline

The web interface features an AI assistant named “Beonline” that understands natural language commands:

Try these prompts:

1. List the menu:

text

What drinks are on the menu right now?

2. Place an order:

text

Place a medium oat latte for Maya with one extra shot.

3. Check order status:

text

List open orders and tell me which tickets are ready to pick up.

4. Custom drinks:

text

Can I get a large caramel macchiato with oat milk?

How the AI Works:

  • Uses the Model Context Protocol (MCP) to communicate with the backend
  • Runs Hugging Face Transformers in the browser (no API keys needed)
  • Same business logic powers the AI, CLI, and HTTP API
  • Shows real-time tool activity as it processes your request

🏗️ Understanding the Architecture

The Effect Coffee Shop is a masterclass in Onion Architecture. Let’s break down the layers:

1. Domain Layer (packages/coffee/core)

  • What it is: The heart of the application
  • Contents:
    • Domain models (Order, Menu, Customer)
    • Business logic (place_order, brew_coffee)
    • Ports (interfaces for external dependencies)
  • Key principle: Zero external dependencies

2. Application Layer (packages/coffee/external)

  • What it is: Implementation of the domain ports
  • Contents:
    • Persistence (in-memory, SQLite, D1, Postgres)
    • External service integrations
    • Repository implementations

3. Presentation Layer (packages/coffee/presentation)

  • What it is: Interfaces for user interaction
  • Contents:
    • HTTP route handlers
    • CLI command handlers
    • MCP tool definitions

4. Runtime Shells (apps/backendapps/web)

  • What it is: Composition roots for different environments
  • Options:
    • Bun runtime (local development)
    • Cloudflare Workers
    • AWS/Postgres

Why This Architecture Matters:

✅ Testability – Core logic can be tested without infrastructure
✅ Maintainability – Changes are isolated to specific layers
✅ Flexibility – Swap databases or presentation without rewriting domain logic
✅ Shared Logic – Same code powers multiple interfaces


🛠️ Technology Stack Breakdown

LayerTechnologyWhy
Package ManagerBunFast, integrated monorepo support
Build SystemTurborepoSmart caching, parallel execution
Backend RuntimeBunHigh performance, TypeScript native
Backend FrameworkEffect v4Type-safe effects, robust error handling
DatabaseSQLiteLightweight, good for development
ORMPrismaType-safe database queries
FrontendReact + ViteFast development, excellent DX
Frontend HostingViteHMR, optimized builds
AI IntegrationHugging Face TransformersOn-device inference, no API keys
ProtocolMCPStandardized AI-tool interaction
TestingBun testFast, built-in test runner

📊 Performance Highlights

The project demonstrates impressive performance characteristics:

  • 8-12x faster TypeScript compilation (thanks to TypeScript 7.0)
  • 26% memory reduction in large projects
  • 13x faster editor error detection
  • Bun runtime with 4x faster installs than npm

💡 Key Takeaways for Your Projects

  1. Start with Domain Logic — Keep your business rules isolated from frameworks.
  2. Leverage TypeScript Fully — Use TypeScript 7.0’s performance improvements.
  3. Consider Effect Library — For complex applications, functional effects make error handling and concurrency more predictable.
  4. Build Multiple Interfaces — Design your core logic to work with HTTP, CLI, and even AI interfaces.
  5. Think Beyond REST — Consider MCP for AI integration, GraphQL for flexible APIs, or CLI for developer tools.
  6. Use Modern Tooling — Bun, Vite, and Turborepo significantly improve developer experience.

🚧 Troubleshooting Common Issues

Port 3000 in Use

bash

sudo lsof -i :3000
sudo kill -9 PID

Bun Not Found

bash

# Add Bun to PATH
export PATH="$HOME/.bun/bin:$PATH"

Dependencies Not Installing

bash

# Clean install
rm -rf node_modules bun.lock
bun install

TypeScript Errors

bash

# TypeScript 7.0.2 is required
tsc --version  # Should show 7.0.2

🎓 Further Learning Resources


🎉 Conclusion: What We’ve Learned

The Effect Coffee Shop project is more than just a demo — it’s a blueprint for building production-grade full-stack TypeScript applications.

We’ve successfully:

  • ✅ Set up a full-stack TypeScript monorepo
  • ✅ Built an application with Onion Architecture
  • ✅ Exposed the same logic through HTTP, CLI, and AI interfaces
  • ✅ Integrated an on-device AI assistant
  • ✅ Used modern tooling (Bun, Vite, Turborepo, TypeScript 7.0)

The result: A maintainable, testable, and scalable application that demonstrates real-world patterns.


📢 Call to Action

Ready to build your own full-stack TypeScript application?

  1. Clone the repository: git clone https://github.com/kevinmichaelchen/effect-coffee-shop.git
  2. Explore the code: Look at the domain logic, presentation layers, and runtime configurations
  3. Build your own project: Use this architecture as a starting point for your next full-stack application
  4. Contribute: The project is open-source — submit issues, PRs, or suggestions!

📱 Connect With Me

Have questions about this setup or want to share your own experience? Reach out!

  • 🐦 Twitter: [@yourhandle]
  • 🐙 GitHub: [@yourgithub]
  • 📧 Email: [your@email.com]

Happy coding, and may your coffee always be fresh and your types always be safe! ☕🚀


📚 Blog Post Meta Summary

Title: Building a Full-Stack TypeScript Application with Onion Architecture
URL Slug: full-stack-typescript-onion-architecture-effect-coffee-shop
Reading Time: ~15 minutes
Skill Level: Intermediate to Advanced
Publish Date: August 31, 2026

SEO Keywords:

  • Full-stack TypeScript
  • Onion Architecture
  • Effect library
  • Bun monorepo
  • AI integration MCP
  • TypeScript 7.0