# FreeLLM API Monorepo Workspace Structure: How Shared, Server, Client, and CLI Are Organized

> Explore the FreeLLM API monorepo structure. Learn how shared, server, client, and CLI workspaces are organized and managed for efficient development. Discover cross-package builds and shared TypeScript definitions.

- Repository: [Tashfeen/freellmapi](https://github.com/tashfeenahmed/freellmapi)
- Tags: architecture
- Published: 2026-08-31

---

**The FreeLLM API uses a Yarn/npm-style monorepo with four workspaces—**shared**, **server**, **client**, and **cli**—where the root [`package.json`](https://github.com/tashfeenahmed/freellmapi/blob/main/package.json) orchestrates cross-package builds and the `shared` workspace exports TypeScript definitions consumed via the workspace protocol.**

The **tashfeenahmed/freellmapi** repository implements a clean monorepo workspace structure that separates concerns across a shared library, Express server, React dashboard, and command-line interface. This architecture enables type-safe cross-package imports while maintaining independent deployment artifacts. Understanding how these four workspaces interact is essential for contributing to or deploying the FreeLLM API proxy and admin tools.

## Root Package Configuration and Workspace Declaration

The monorepo workspace structure is defined in the root [`package.json`](https://github.com/tashfeenahmed/freellmapi/blob/main/package.json) using the standard npm workspaces field. This configuration declares four distinct packages that npm/Yarn treats as linked dependencies.

```json
{
  "private": true,
  "workspaces": [
    "shared",
    "server",
    "client",
    "cli"
  ],
  "scripts": {
    "dev": "concurrently --kill-others-on-fail --names server,client \"npm run dev -w server\" \"npm run dev -w client\"",
    "build": "npm run build -w server && npm run build -w cli && npm run build -w client",
    "test": "npm run test -w server && npm run test -w cli && npm run test -w client --if-present"
  }
}

```

Each workspace maintains its own [`package.json`](https://github.com/tashfeenahmed/freellmapi/blob/main/package.json) and [`tsconfig.json`](https://github.com/tashfeenahmed/freellmapi/blob/main/tsconfig.json), enabling independent TypeScript compilation targets while preserving type safety across package boundaries.

## The Four Workspace Architecture

### Shared Workspace (Common Types)

The **shared** workspace serves as the foundation for type safety across the monorepo. Located at [`shared/types.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/shared/types.ts), it exports TypeScript interfaces and utilities that both the server and CLI consume.

```ts
// server/src/lib/config.ts
import { ProviderConfig } from "shared/types";

```

Using the workspace protocol, the server and CLI packages import these definitions without publishing to an external registry. This ensures that changes to core data structures propagate immediately to dependent packages during development.

### Server Workspace (API Proxy)

The **server** workspace implements the core FreeLLM API logic as an Express application. The entry point at [`server/src/app.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/app.ts) bootstraps the HTTP server and mounts the routing layer.

Key services within this workspace include:

- **Router service** ([`server/src/services/router.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/router.ts)) – Implements model selection logic based on health checks, rate-limit ledgers, and fallback-chain strategies.
- **Rate-limit ledger** ([`server/src/services/ratelimit.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/ratelimit.ts)) – Tracks RPM (requests per minute), RPD (requests per day), TPM (tokens per minute), and TPD (tokens per day) counters per API key using an in-memory store backed by SQLite.
- **Provider adapters** (`server/src/providers/`) – Each file implements a common `Provider` interface exposing `chatCompletion()` and `streamChatCompletion()` methods for different LLM backends.
- **Health service** ([`server/src/services/health.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/health.ts)) – Periodically probes provider keys to maintain fresh availability status.

### Client Workspace (Admin Dashboard)

The **client** workspace delivers the administrative interface built with **React** and **Vite**. The root component at [`client/src/App.tsx`](https://github.com/tashfeenahmed/freellmapi/blob/main/client/src/App.tsx) renders the dashboard that visualizes model routing decisions, key usage analytics, and system health metrics. This package is compiled independently from the server, allowing deployment to static hosting or CDN while communicating with the server API at runtime.

### CLI Workspace (Management Tools)

The **cli** workspace provides operational tooling for system administrators. The entry point at [`cli/src/index.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/cli/src/index.ts) exposes commands that interact directly with the server's SQLite database and HTTP endpoints:

- `freellmapi doctor` – Runs health checks against configured providers
- `freellmapi config` – Manages local configuration profiles
- `freellmapi key import` – Imports API keys into the rate-limiting store

## Cross-Workspace Dependencies and Import Patterns

The monorepo workspace structure leverages npm's workspace protocol to link packages internally. When the server package imports `shared/types`, it resolves to the local filesystem rather than the npm registry. This eliminates version drift between the API implementation and its type definitions.

Each workspace compiles TypeScript independently, allowing the server to target Node.js ESM while the client targets browser-compatible ES modules. The **shared** package typically emits declaration files only, as it contains no runtime logic requiring bundling.

## Development Workflow and Concurrent Execution

The root [`package.json`](https://github.com/tashfeenahmed/freellmapi/blob/main/package.json) scripts coordinate development across the server and client workspaces using the `concurrently` package. Running `npm run dev` launches both the Express server and Vite dev server simultaneously.

```bash

# Install dependencies for all workspaces

npm ci

# Start server and client with hot reloading

npm run dev

# In another terminal, run CLI diagnostics

npx freellmapi doctor

```

The build pipeline sequences compilation to respect dependencies: the server and CLI build first (as they may run in Node.js environments), followed by the client static assets. Tests execute across all workspaces that define test scripts, using the `--if-present` flag to skip packages without test suites.

## Summary

- The **root [`package.json`](https://github.com/tashfeenahmed/freellmapi/blob/main/package.json)** declares four workspaces (`shared`, `server`, `client`, `cli`) and provides orchestration scripts using `concurrently` and npm workspace flags (`-w`).
- The **shared workspace** at [`shared/types.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/shared/types.ts) exports TypeScript definitions imported by both the server and CLI via the workspace protocol.
- The **server workspace** implements the Express proxy with routing logic in [`server/src/services/router.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/router.ts), rate limiting in [`server/src/services/ratelimit.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/ratelimit.ts), and provider adapters under `server/src/providers/`.
- The **client workspace** is a Vite-powered React application with its entry point at [`client/src/App.tsx`](https://github.com/tashfeenahmed/freellmapi/blob/main/client/src/App.tsx).
- The **CLI workspace** at [`cli/src/index.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/cli/src/index.ts) exposes management commands including `doctor`, `config`, and `key import`.

## Frequently Asked Questions

### How does the shared workspace export types to other packages?

The **shared** workspace exports TypeScript interfaces from [`shared/types.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/shared/types.ts) that other packages import using bare module specifiers like `import { ProviderConfig } from "shared/types"`. Because the root [`package.json`](https://github.com/tashfeenahmed/freellmapi/blob/main/package.json) declares `"workspaces": ["shared", ...]`, npm automatically symlinks the shared package into `node_modules`, resolving these imports to the local filesystem during both development and builds.

### What npm scripts are used to run the monorepo in development?

The root [`package.json`](https://github.com/tashfeenahmed/freellmapi/blob/main/package.json) defines a `dev` script that executes `concurrently --kill-others-on-fail --names server,client "npm run dev -w server" "npm run dev -w client"`. This launches the Express server and Vite client dev server simultaneously. The `-w` (workspace) flag ensures commands execute in the correct package context, while `--kill-others-on-fail` terminates both processes if either crashes.

### Where is the routing logic implemented in the server workspace?

The primary routing logic resides in [`server/src/services/router.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/router.ts), which selects the optimal LLM provider per request based on health status, rate-limit ledger data from [`server/src/services/ratelimit.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/ratelimit.ts), and fallback-chain configuration. The Express application mounts this router in [`server/src/app.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/app.ts) to handle incoming API requests.

### How are provider adapters structured in the codebase?

Provider adapters are located in the `server/src/providers/` directory, with one file per LLM service (e.g., OpenAI, Anthropic). Each adapter implements a standardized **Provider** interface exposing two methods: `chatCompletion()` for standard requests and `streamChatCompletion()` for Server-Sent Events streaming. This uniform interface allows the router in [`server/src/services/router.ts`](https://github.com/tashfeenahmed/freellmapi/blob/main/server/src/services/router.ts) to treat all backends interchangeably while maintaining provider-specific authentication and request formatting.