Architectural Overview of Logto: Monorepo Structure and Component Breakdown
Logto is a TypeScript-based monorepo organized into npm workspaces that combines a Koa.js OIDC/OAuth 2.1 backend, PostgreSQL database layer, React-based admin and experience UIs, and pluggable connectors for social/SMS/email authentication.
This architectural overview of Logto examines how the identity platform structures its codebase across distinct runtime concerns. The repository uses npm workspaces to separate backend services, frontend applications, database schemas, and shared utilities while maintaining a unified build pipeline and TypeScript implementation.
Monorepo Organization and Workspace Structure
Logto adopts a monorepo architecture where all components share a single TypeScript codebase and dependency tree. The repository organizes functionality into npm workspaces, each encapsulating a specific domain such as authentication logic, database schemas, or user interfaces.
Key workspace categories include:
- Core services handling OIDC/OAuth flows and management APIs
- Database packages defining PostgreSQL schemas and migration scripts
- Frontend applications built with React and Vite
- Pluggable connectors for external identity providers
- Shared toolkits providing common utilities across the stack
Core Backend Architecture
The backend core (@logto/core) implements the complete OIDC/OAuth 2.1 provider and management API. Built on Koa.js, this layer handles all server-side business logic, token issuance, and tenant isolation.
The Core service exposes two primary ports:
- Port
3001for user-facing OpenID Connect endpoints - Port
3002for administrative API operations
To start the Core in development mode:
# Ensure PostgreSQL is running and DB_URL is set
export DB_URL="postgres://postgres:p0stgr3s@localhost:5432/logto"
# Install dependencies and launch the Core
pnpm i
pnpm dev # starts Core on http://localhost:3001 (user) and http://localhost:3002 (admin)
Key source files include:
packages/core/src/index.ts– Application entry point that initializes the Koa server and OIDC providerpackages/core/src/routes.ts– Route definitions for authentication and management endpointspackages/core/package.json– Dependency configuration includingoidc-providerlibrary
Database Schema and Migration System
Data persistence relies on PostgreSQL, with schema definitions and type safety managed through the @logto/schemas package. This workspace contains SQL migration files, alteration scripts, and TypeScript interfaces that mirror the database structure.
Critical files in this layer:
packages/schemas/src/alterations/001_initial.sql– Initial database migrationpackages/schemas/src/foundations/types.ts– TypeScript type definitions for database entitiespackages/schemas/package.json– Schema package configuration
The Core service connects to PostgreSQL via the DB_URL environment variable, loading schema definitions at startup to ensure type-safe database interactions.
Frontend Applications: Admin Console and Experience
Logto provides two distinct React-based single-page applications (SPAs), both built with Vite for rapid development cycles.
Admin Console
The Admin Console (@logto/console) serves as the management dashboard where administrators configure tenants, applications, and access policies. It authenticates against the Core's management API (port 3002) using service-account tokens.
Key implementation files:
packages/console/src/App.tsx– Root application componentpackages/console/src/pages/Dashboard.tsx– Main dashboard interfacepackages/console/package.json– Frontend dependencies and build configuration
The console typically runs on port 5002 during development.
Experience UI
The Experience package (@logto/experience) renders the customizable sign-in and sign-up flows presented to end-users. When authentication initiates, the Core redirects users to this SPA (port 5001), which collects credentials and returns them to complete the OIDC flow.
Essential source locations:
packages/experience/src/App.tsx– Experience application entry pointpackages/experience/src/pages/SignIn.tsx– Sign-in interface componentpackages/experience/package.json– Build tooling and dependencies
Connector Ecosystem
Connectors provide pluggable integration with external identity providers and notification services. Each connector resides in a dedicated package under packages/connectors/, implementing a standard interface defined in @logto/toolkit/connector-kit.
Connector types include:
- Social connectors (GitHub, Google, Apple) for OAuth 2.0/SAML authentication
- SMS connectors for phone verification
- Email connectors for SMTP or API-based email delivery
The Core discovers connector packages at runtime and loads them as plugins. For example, connector-github handles the OAuth 2.0 handshake when tenants enable "Login with GitHub."
Implementation from packages/connectors/connector-github/src/index.ts:
import { createConnector } from '@logto/connector-kit';
import { fetch } from 'node-fetch';
export const githubConnector = createConnector({
name: 'GitHub',
type: 'social',
async getAuthorizationUrl() {
const redirectUri = `${process.env.BASE_URL}/callback/github`;
return `https://github.com/login/oauth/authorize?client_id=${process.env.GITHUB_CLIENT_ID}&redirect_uri=${encodeURIComponent(redirectUri)}`;
},
async getUserInfo(code: string) {
// Exchange code for token and fetch user profile
const tokenRes = await fetch('https://github.com/login/oauth/access_token', {
method: 'POST',
body: new URLSearchParams({
client_id: process.env.GITHUB_CLIENT_ID,
client_secret: process.env.GITHUB_CLIENT_SECRET,
code,
}),
});
const token = await tokenRes.text();
const profileRes = await fetch('https://api.github.com/user', {
headers: { Authorization: `token ${token}` },
});
return await profileRes.json();
},
});
Additional connector files:
packages/connectors/connector-github/package.json– GitHub connector manifestpackages/connectors/connector-smtp/package.json– SMTP email connector configuration
Shared Toolkit and API Specifications
The toolkit packages (@logto/toolkit/*) contain reusable libraries consumed by multiple workspaces. These utilities provide password hashing algorithms, JWT handling, internationalization (i18n) support, and database abstraction layers.
Key toolkit components:
packages/toolkit/core-kit/src/index.ts– Core utilities and helperspackages/toolkit/core-kit/package.json– Toolkit configuration
The @logto/api package exports the OpenAPI (Swagger) specification that documents the Core's management and authentication endpoints. This specification, located at packages/api/openapi.yaml, generates client SDKs for various programming languages.
CLI and Development Tools
The CLI (@logto/cli) assists developers with project scaffolding, database seeding, and migration execution. It enables initialization of new Logto instances through npm init @logto and manages database alterations across environments.
CLI entry point: packages/cli/package.json
Demo applications (@logto/demo-app) illustrate integration patterns for web and mobile clients. These examples demonstrate SDK usage for signing in, obtaining tokens, and calling protected resources, with the main entry at packages/demo-app/src/main.ts.
Runtime Architecture and Request Flow
Understanding how these components interact reveals the complete architectural overview of Logto:
-
Development startup – Running
pnpm devinitializes the Core service on ports3001and3002, connects to PostgreSQL viaDB_URL, and registers the OIDC provider. -
Administration flow – Administrators access the Console SPA (port
5002), which authenticates against the Core's management API to create tenants and configure policies. -
End-user authentication – Client applications redirect users to the Core's
/experienceendpoint, which serves the Experience UI (port5001). The UI collects credentials and returns them to the Core to complete the OIDC token issuance. -
External integration – When social login is configured, the Core delegates authentication to the appropriate connector package (e.g.,
connector-github), which handles the external OAuth 2.0 flow. -
Client integration – Applications use Logto SDKs (generated from the OpenAPI spec) to interact with the Core endpoints, as shown in this client initialization from
packages/sdk/js/src/client.ts:
import { createLogtoClient } from '@logto/client';
// Initialise the SDK with the Core endpoint and your app ID
const logto = createLogtoClient({
endpoint: 'http://localhost:3001',
appId: 'your-app-id',
});
// Redirect the user to the sign‑in page
await logto.signIn();
// After the redirect back, fetch the access token
const accessToken = await logto.getAccessToken();
Summary
- Logto organizes its identity platform as a TypeScript monorepo using npm workspaces to separate concerns while sharing build tooling.
- The Core (
@logto/core) provides the OIDC/OAuth 2.1 implementation on Koa.js, exposing user and admin APIs on separate ports. - PostgreSQL persistence is managed through the
@logto/schemaspackage, which maintains migration files and TypeScript type definitions. - Two React/Vite frontends serve distinct purposes: the Admin Console for management and the Experience UI for end-user authentication flows.
- Connectors enable pluggable integration with social providers and notification services, implementing a standard interface from the connector toolkit.
- Shared toolkits provide cross-cutting concerns like cryptography and i18n, while the CLI and OpenAPI specifications facilitate deployment and client generation.
Frequently Asked Questions
What backend framework does Logto use for its authentication server?
Logto implements its Core authentication service using Koa.js, a lightweight Node.js framework. The Core package (@logto/core) integrates the oidc-provider library to handle OIDC/OAuth 2.1 flows, with entry point logic defined in packages/core/src/index.ts and routing configured in packages/core/src/routes.ts.
How does Logto manage database schema changes across versions?
Database migrations are maintained in the @logto/schemas package, specifically within the packages/schemas/src/alterations/ directory. Initial schemas are defined in files like 001_initial.sql, while TypeScript type definitions in packages/schemas/src/foundations/types.ts ensure compile-time safety. The CLI (@logto/cli) executes these migrations during deployment.
What distinguishes the Admin Console from the Experience UI in Logto's architecture?
The Admin Console (@logto/console) is an internal management interface running on port 5002 that configures tenants, applications, and policies via the Core's management API. The Experience UI (@logto/experience) runs on port 5001 and presents customizable sign-in/sign-up flows to end-users, communicating with the Core's OIDC endpoints to complete authentication sequences.
How are external identity providers integrated into Logto?
External providers are integrated through connectors, which are separate packages following the @logto/connector-<name> naming convention. Each connector implements an interface from @logto/toolkit/connector-kit and resides in packages/connectors/. The Core discovers these packages at runtime, allowing tenants to enable social login (like GitHub in packages/connectors/connector-github/src/index.ts) without modifying the Core codebase.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →