i18n and Shared Configuration
Purpose and Scope
This page explains the small shared packages that make Cal.diy consistent across applications and libraries: internationalization utilities, shared TypeScript compiler presets, styling configuration dependencies, and a shared Day.js wrapper. These packages are not end-user features by themselves, but they form part of the foundation that feature packages, application packages, and self-hosted deployments rely on. When a contributor changes translations, TypeScript inheritance, Tailwind-related configuration, or date handling assumptions, the effects can spread across the monorepo. Understanding these package boundaries helps contributors make localized changes without accidentally creating divergent application behavior.
Cal.diy is organized as a workspace monorepo, so packages communicate through named workspace packages rather than ad hoc relative imports. The source evidence for this page shows several private packages that are meant to be consumed internally: one for internationalization, one for TypeScript configuration, one for shared styling configuration dependencies, and one for Day.js. Their manifests expose a clear design pattern: each package declares a narrow public surface, sets its workspace identity with an at-scoped package name, and keeps implementation details behind package exports or package files. Sources: packages/i18n/package.json, packages/tsconfig/package.json, packages/config/package.json, packages/dayjs/package.json
These shared packages are especially important in a self-hosted project because local setup, Docker setup, production builds, and development workflows all expect the repository to build as one coordinated system. The official Docker documentation tells operators to prepare environment configuration, start the stack, and open the web app after initialization; behind that runtime workflow, the web application still depends on the same compile-time and shared-library packages used during local development. The practical takeaway is that infrastructure configuration and code configuration are separate layers, but both must remain coherent for a reliable installation.
Relevant Source Files
- packages/i18n/package.json — Defines the internal internationalization package, its package description, dependency on i18next, and exported entrypoints for server utilities, Next i18next configuration, and locale files.
- packages/tsconfig/README.md — Documents the intent of the shared TypeScript configuration package: base tsconfig files from which other tsconfig files inherit.
- packages/tsconfig/package.json — Publishes the shared TypeScript configuration package surface, including the base, Next.js, and React library presets made available as package files.
- packages/config/package.json — Defines the shared configuration package that centralizes styling-related dependencies such as Tailwind variants, scrollbar support, Radix Tailwind helpers, animation CSS, and typography tooling.
- packages/dayjs/package.json — Defines the shared Day.js package used by the monorepo as Cal.diy’s Day.js shared library.
Core Shared Packages
The internationalization package is named as an internal Cal.diy package and describes itself as internationalization utilities and translations for Cal.diy. Its public surface is intentionally explicit: it exports a server entrypoint, a Next i18next configuration entrypoint, and a wildcard locale file path. That combination tells contributors that localization work is split between runtime utilities, framework configuration, and translation assets. Instead of treating locale files as arbitrary repository data, the package manifest exposes them as part of the package contract, which makes it easier for application code to depend on a stable locale namespace. Sources: packages/i18n/package.json
The TypeScript configuration package serves a different kind of shared contract. Its README states that the package contains base shared TypeScript configuration files from which other TypeScript configuration files inherit. The package manifest then lists the files that make up that contract: a base preset, a Next.js preset, and a React library preset. This means the monorepo can express project-specific compiler settings while still inheriting common defaults. For contributors, the important rule is to choose the closest shared preset before adding local compiler overrides, because local divergence can make builds, editor diagnostics, and package boundaries harder to reason about. Sources: packages/tsconfig/README.md, packages/tsconfig/package.json
The configuration package is named as another private internal package and carries dependencies rather than exported JSON files in the supplied manifest. Its dependency list points at shared styling infrastructure: Tailwind variants, scrollbar utilities, Radix helpers for Tailwind, and animation CSS. The package also declares typography tooling as a development dependency. Even though this evidence does not show the consuming configuration files, the manifest establishes the package as the place where Cal.diy centralizes reusable styling configuration dependencies. That reduces the chance that individual packages pick incompatible versions of styling helpers or silently drift from the shared design system behavior. Sources: packages/config/package.json
The Day.js package is a focused wrapper around the date library used by Cal.diy. Its manifest names the package as Cal.diy’s Day.js shared library, points its main entrypoint at a TypeScript index file, and depends on Day.js itself. Date and time behavior is a scheduling platform concern, so centralizing the date library through a workspace package is a useful boundary. Application and feature code can import the shared package rather than each area deciding independently how to load plugins, configure locales, or pin the dependency version. Sources: packages/dayjs/package.json
System-to-Code Mapping
| Concern | Shared package | Public surface shown in evidence | Why it matters |
|---|---|---|---|
| Translations and locale access | @calcom/i18n | Server utilities, Next i18next config, locale wildcard export | Keeps localization assets and i18n runtime configuration behind a stable package boundary. |
| Compiler inheritance | @calcom/tsconfig | base.json, nextjs.json, react-library.json | Gives apps and libraries common TypeScript defaults while allowing targeted project-specific configs. |
| Styling configuration dependencies | @calcom/config | Tailwind-related dependencies and typography tooling | Centralizes shared styling infrastructure so packages do not manage incompatible helper versions. |
| Date library access | @calcom/dayjs | TypeScript main entrypoint backed by Day.js | Provides a single monorepo-level date utility package for scheduling and time-related code. |
The mapping above is intentionally package-oriented rather than file-by-file. These packages are best understood as contracts between many consumers and a small number of maintainers. A feature package should not need to understand every locale file to use translations, and a React library should not have to repeat the complete compiler baseline to participate in the workspace. The manifests show the public names and available surfaces; those are the first places to check before creating new configuration files, adding a direct dependency, or copying settings from a neighboring package.
Implementation Details and Contribution Guidance
When working on localization, start from the package boundary rather than the consuming page. The internationalization package exports both configuration and locale paths, which implies that translation changes should preserve the distinction between framework setup and content data. A contributor adding or adjusting translations should think about three questions: whether the translation asset belongs under the locale export namespace, whether server-side rendering needs the value through the server entrypoint, and whether framework configuration should remain generic. Keeping those questions separate prevents translation work from becoming entangled with a single application route or component.
When working on TypeScript configuration, use inheritance deliberately. The shared tsconfig README describes the package as the base for other TypeScript configurations, and the package files identify common target contexts: generic base code, Next.js applications, and React libraries. If a package is a React component library, the React library preset is a better starting point than copying settings from an application. If a package is a Next.js app, the Next.js preset should carry framework-specific compiler assumptions. Local overrides should be small and justified, because broad overrides weaken the value of a common compiler baseline. Sources: packages/tsconfig/README.md, packages/tsconfig/package.json
When working on shared styling configuration, treat the configuration package as dependency coordination. The manifest’s dependencies are styling utilities that influence class composition, component states, scrollbars, animation, and typography. Version changes in this package should be reviewed as cross-cutting changes, not as isolated package maintenance, because visual components in other workspaces may rely on the exact behavior of those helper libraries. A safe workflow is to update the shared package, run formatting and type checks where appropriate, and visually inspect representative UI areas that use shared primitives or Tailwind variants.
When working on dates, use the shared Day.js package rather than adding new direct date library dependencies in feature packages. The manifest pins the Day.js dependency inside the shared package and exposes a TypeScript entrypoint as the package main. That structure is useful for a scheduling product because date formatting, locale behavior, time arithmetic, and calendar integration code should not fragment across multiple libraries or versions. Even small differences in date handling can appear as booking availability bugs, timezone display mismatches, or inconsistent email content, so centralization is a practical reliability measure. Sources: packages/dayjs/package.json
Build and Runtime Considerations
These shared packages sit mostly on the build-time and application-code side of the system, while deployment documentation focuses on runtime environment variables, service startup, and the database-backed application stack. The official Docker flow has operators copy an environment file, update configuration, and start services with Docker Compose. That runtime setup does not replace the package contracts described here; instead, it assumes the built application was compiled with consistent TypeScript presets, styling dependencies, date utilities, and i18n configuration. If a self-hosted instance behaves differently after a code change, check both runtime environment configuration and shared package changes.
Because the packages are private workspace packages, their purpose is internal consistency rather than publication as standalone libraries for external consumers. This affects how changes should be reviewed. A package export or file list change can break many internal imports even if no public external API is involved. A dependency version change can alter generated CSS, translation loading, or date behavior without changing application source. For that reason, contributors should treat these manifests as part of the monorepo’s developer platform. They are small, but they describe assumptions that larger application packages build on.
Compact Reference
| Package | Key manifest fields | Notes for contributors |
|---|---|---|
| @calcom/i18n | private package, side effects disabled, depends on i18next, exports server, Next i18next config, and locale paths | Add localization behavior through the package surface rather than bypassing it from application code. |
| @calcom/tsconfig | private shared config package with base, Next.js, and React library files | Prefer an existing preset before creating local compiler divergence. |
| @calcom/config | private shared configuration package with Tailwind and styling helper dependencies | Review dependency changes as visual and cross-package changes. |
| @calcom/dayjs | private package with a TypeScript main entrypoint and Day.js dependency | Centralize date handling through this package to keep scheduling behavior consistent. |
Next Steps
If you are adding a translated feature, inspect the internationalization package first and keep locale assets, server utilities, and framework configuration separate. If you are creating a new package, choose the shared TypeScript preset that matches its role before introducing local compiler options. If you are changing visual styling infrastructure, treat the configuration package as shared design-system plumbing and test representative components. If you are touching scheduling, availability, or calendar display behavior, prefer the shared Day.js package so that time-related behavior stays consistent across the monorepo.