Naming standards for the Jan monorepo structure
Use lowercase with hyphens for multi-word names:
server/
├── apps/ # Frontend applications
├── services/ # Backend microservices
├── packages/ # Shared libraries
├── infra/ # Infrastructure as Code
├── tools/ # Development tools
├── integrations/ # Third-party integrations
├── docs/ # Documentation
└── tests/ # Test suites
Rules:
- Use descriptive, plural nouns where appropriate (
apps,services,packages) - Single word preferred (
tools,docs) - Hyphenate multi-word directories (
infra-scriptsif needed) - No underscores in directory names
Frontend apps in apps/ use kebab-case:
apps/
├── web/ # Main web application
├── admin/ # Admin dashboard
├── platform/ # Platform interface
├── mobile/ # Mobile app (future)
└── chrome-extension/ # Browser extension (example)
Rules:
- Lowercase only
- Hyphenate multi-word apps (
chrome-extension,user-portal) - Descriptive and concise
- Avoid abbreviations unless widely known
Backend services in services/ use kebab-case with suffix pattern:
services/
├── llm-api/ # LLM API service
├── mcp-tools/ # MCP tools service
├── media-api/ # Media API service
├── memory-tools/ # Memory tools service
├── realtime-api/ # Realtime API service
└── response-api/ # Response API service
Rules:
- Lowercase kebab-case
- End with
-apior-toolsor-servicefor clarity - Match Docker image naming
- Consistent across documentation
Shared packages in packages/ use kebab-case with prefix pattern:
packages/
├── shared-ui/ # Shared React components
├── shared-types/ # TypeScript type definitions
├── shared-utils/ # Common utilities
├── shared-config/ # Shared configuration
└── go-common/ # Shared Go packages
Rules:
- Prefix with
shared-for cross-app packages - Language-specific packages use language name (
go-common,py-utils) - Descriptive suffix (
-ui,-types,-utils)
.env # Root environment file
.env.example # Example environment template
.gitignore # Git ignore rules
docker-compose.yml # Main compose file
pnpm-workspace.yaml # pnpm workspace config
turbo.json # Turborepo config (if used)
Rules:
- Lowercase
- Use standard config file names
- Hyphenate multi-word configs (
docker-compose.yml)
docs/
├── README.md # Documentation index
├── quickstart.md # Getting started guide
├── repo-naming.md # This document
└── api/
├── README.md
└── llm-api.md
Rules:
- Lowercase kebab-case with
.mdextension README.md(uppercase) for index files- Descriptive names (
authentication.md,deployment-guide.md) - Match directory structure where relevant
TypeScript/JavaScript:
- Components:
PascalCase.tsx(e.g.,UserProfile.tsx) - Utilities:
camelCase.ts(e.g.,formatDate.ts) - Hooks:
camelCase.tswithuseprefix (e.g.,useAuth.ts) - Types:
PascalCase.types.ts(e.g.,User.types.ts)
Go:
- Files:
snake_case.go(e.g.,cmd_setup.go,utils.go) - Packages: lowercase single word (e.g.,
config,telemetry)
infra/docker/
├── infrastructure.yml # Core infrastructure
├── services-api.yml # API services
├── services-mcp.yml # MCP services
├── services-memory.yml # Memory services
├── services-realtime.yml # Realtime services
└── observability.yml # Monitoring stack
Pattern: {category}.yml or services-{type}.yml
Rules:
- Lowercase kebab-case
- Group by function/category
- Prefix with
services-for service definitions - Single word for infrastructure types
Format: registry.domain.com/server/{service}:{tag}
Examples:
registry.menlo.ai/server/llm-api:dev-abc123registry.menlo.ai/server/mcp-tools:prod-v1.2.3
Rules:
- Use kebab-case for service names
- Tag format:
{env}-{identifier}(e.g.,dev-sha,prod-v1.0.0)
infra/k8s/
├── namespace.yaml
├── llm-api-deployment.yaml
├── mcp-tools-service.yaml
└── ingress.yaml
Pattern: {resource-name}-{type}.yaml or {type}.yaml
Rules:
- Lowercase kebab-case
- Suffix with resource type (
-deployment,-service,-configmap) - Standalone types use singular (
namespace.yaml,ingress.yaml)
Format: {type}/{scope}-{description} or {type}/{description} (for cross-cutting changes)
Types:
feat/- New featuresfix/- Bug fixesrefactor/- Code refactoringdocs/- Documentation updateschore/- Maintenance taskstest/- Test additions/fixes
Scopes (optional but recommended for monorepo):
web- Web app changesadmin- Admin app changesplatform- Platform app changesservices- Backend services (general)llm-api,mcp-tools, etc. - Specific serviceshared- Shared packagesinfra- Infrastructure changes
Examples:
With scope (recommended for monorepo):
feat/web-user-authentication- New auth feature in web appfix/llm-api-memory-leak- Bug fix in LLM API servicefeat/admin-dashboard-redesign- Admin app featurerefactor/shared-refactor-types- Shared package refactoringchore/infra-update-k8s-configs- Infrastructure update
Without scope (for cross-cutting changes):
docs/update-api-guide- Documentation affecting multiple serviceschore/upgrade-dependencies- Dependency updates across monoreporefactor/monorepo-structure- Structural changes
main- Main development branch (triggers dev deployments)dev-test- Testing branch (triggers dev deployments)release- Production branch (triggers prod deployments)
Format: @jan/{package-name}
Examples:
@jan/shared-ui@jan/shared-types@jan/shared-utils
Format: server/{service-name}:{tag}
Examples:
server/llm-api:latestserver/mcp-tools:dev-abc123
Format: github.com/janhq/server/{path}
Examples:
github.com/janhq/server/tools/jan-cligithub.com/janhq/server/pkg/config
All workflows live in .github/workflows/ with the following organization:
.github/workflows/
├── ci-backend-dev.yml # Backend services (dev/main branches)
├── ci-backend-prod.yml # Backend services (release branch)
├── ci-app-web-dev.yml # Web app dev/main
├── ci-app-web-prod.yml # Web app release
├── ci-app-admin-dev.yml # Admin app dev/main
├── ci-app-admin-prod.yml # Admin app release
├── ci-app-platform-dev.yml # Platform app dev/main
├── ci-app-platform-prod.yml # Platform app release
├── ci-packages.yml # Shared packages validation
├── config-drift.yml # Config validation
└── _reusable-docker.yml # Reusable Docker build template
Format: ci-{component}-{environment}.yml
Components:
backend- Backend microservicesapp-{name}- Frontend applications (web, admin, platform)packages- Shared packages/libraries- Component-specific names (e.g.,
config-drift)
Environments:
dev- Development/staging (triggers onmain,dev-testbranches)prod- Production (triggers onreleasebranch)- No suffix - Environment-agnostic validation workflows
Special Prefixes:
_(underscore) - Reusable workflow templates (e.g.,_reusable-docker.yml)
ci-backend-dev.yml- Backend services for dev environmentci-app-web-prod.yml- Web app production deploymentci-app-checkout-dev.yml- New checkout app dev workflowci-packages.yml- Shared packages validation_reusable-node-build.yml- Reusable Node.js build template
dev.yml- Too generic, unclear what it buildsweb-app-ci.yml- Wrong order, should beci-app-web-*.ymlci-web.yml- Missingapp-prefix for frontend appsbackend.yml- Missingci-prefix and environment suffixreusable-docker.yml- Missing underscore prefix
When adding a new frontend app (e.g., mobile), create:
.github/workflows/
├── ci-app-mobile-dev.yml # Mobile app dev/main
└── ci-app-mobile-prod.yml # Mobile app release
Template for dev workflow:
name: CI - Mobile App (Dev)
on:
push:
branches: [main, dev-test]
paths:
- "apps/mobile/**"
- "packages/shared-ui/**"
- "packages/shared-types/**"
- "packages/shared-utils/**"
pull_request:
paths:
- "apps/mobile/**"
jobs:
build-and-test:
# ... implementation- Directory:
apps/new-app/ - Workflows:
ci-app-new-app-dev.ymlci-app-new-app-prod.yml
- Package:
@jan/new-app - Branch:
feat/add-new-app
- Directory:
services/new-service/ - Workflow: Include in
ci-backend-dev.ymlandci-backend-prod.yml - Docker:
server/new-service:tag - Compose: Add to
infra/docker/services-api.yml
- Directory:
packages/shared-new/ - Workflow: Include in
ci-packages.yml - NPM:
@jan/shared-new - Workspace: Auto-detected by
pnpm-workspace.yaml
Before committing new files/directories, verify:
- Names follow kebab-case (lowercase with hyphens)
- Workflow files use
ci-{component}-{env}.ymlpattern - Reusable workflows prefixed with underscore
- Directories use plural nouns where appropriate
- No spaces or special characters (except
-and_) - Consistent with existing naming patterns
- Git branch follows
{type}/{description}format - Package names use organization scope (
@jan/)
When migrating an existing app into the monorepo:
- Rename directory to match
apps/orservices/convention - Create workflows following
ci-app-{name}-{env}.ymlpattern - Update package.json name to
@jan/{name}if applicable - Add to workspace in
pnpm-workspace.yaml(auto if inapps/) - Update imports to use monorepo package references
- Document in
docs/with matching kebab-case filename
- Monorepo Best Practices
- Semantic Versioning
- Conventional Commits
- GitHub Actions Naming Best Practices
Questions? Ask in #engineering or open an issue with the documentation label.