Shared Library (libs/shared)
libs/shared is the cross-app TypeScript package. Any code reused by two or more of apps/api, apps/web, or apps/mobile lives here.
Importing from shared
Always import from the public barrel — never from internal paths:
ts
// ✅ Correct
import { UserRole, AuthUser, isAdminRole } from '@folio/shared';
// ❌ Wrong — fragile internal path
import { UserRole } from '../../libs/shared/src/lib/auth/roles';The alias @folio/shared is defined in tsconfig.base.json and resolves to libs/shared/src/index.ts.
What lives in shared
libs/shared/src/lib/
├── contracts/ # Request / response DTO types
├── auth/ # Role constants, permission predicates
├── validation/ # Shared validator functions (no HTTP deps)
└── utils/ # Date helpers, string helpers, etc.Contracts
Contracts are TypeScript interfaces for the data shapes passed between API and clients.
Adding a new contract
- Create a file in
libs/shared/src/lib/contracts/:
ts
// libs/shared/src/lib/contracts/tags.ts
export interface Tag {
id: string;
name: string;
createdAt: string;
}
export interface CreateTagDto {
name: string;
}
export interface UpdateTagDto {
name?: string;
}- Export it from
libs/shared/src/index.ts:
ts
export * from './lib/contracts/tags';- Use in API (TypeScript service/controller) and in Web/Mobile (React components).
Auth helpers
libs/shared/src/lib/auth/ contains:
roles.ts— role predicates (isAdminRole,hasAnyRole)- Role enum source from contracts (
UserRole.USER,UserRole.ADMIN)
Example:
ts
import { UserRole, isAdminRole } from '@folio/shared';
if (!isAdminRole(req.user.role)) {
return res.status(403).json({ message: 'Forbidden' });
}Validation helpers
libs/shared/src/lib/validation/ contains validators that work without any HTTP framework dependency (no Express, no React):
ts
import { isValidIsbn } from '@folio/shared';
if (!isValidIsbn(dto.isbn)) {
throw new ValidationError('Invalid ISBN format');
}Utilities
libs/shared/src/lib/utils/ contains:
formatBirthDate(date: string | null)— safely formats author dates including historical formats- String helpers, slug generation, etc.
Rules for shared code
- No HTTP framework imports in shared (no Express, no React, no Expo).
- No database imports in shared.
- Barrel-export everything through
libs/shared/src/index.ts. - Keep it minimal — shared is for truly reused code, not a dumping ground.
- Add tests in
libs/shared/src/__tests__/for any non-trivial shared logic.
Building shared
The shared lib is built as part of the monorepo:
sh
npx nx run shared:buildOr it's built automatically when any app that depends on it is built.