Skip to main content

Creating Services and Libraries

The CoW Protocol BFF monorepo uses NX generators to scaffold new projects with proper TypeScript, Docker, and configuration setup.

Available Generators

Three main generators are available:
CommandPurpose
yarn new:fastifyREST API services
yarn new:nodeBackground workers, CLI tools
yarn new:libShared libraries

Fastify API Services

yarn new:fastify
Running the Fastify generator creates a complete API structure with:
  • App configuration (src/app/app.ts)
  • Entry point (src/main.ts)
  • Docker setup
  • ESLint settings
  • Testing infrastructure

Route Organization

Keep route schemas in separate files (e.g., *.schemas.ts). Do not inline JSON schemas in route handlers.

Post-Generation Steps

  1. Add the new service to docker-compose.yml with appropriate networking and environment configuration
  2. Update CI/CD pipeline configurations
  3. Configure environment variables

Node.js Applications

yarn new:node
The Node.js generator supports:
  • Background workers
  • Message queue consumers
  • Scheduled jobs
  • CLI tools

Bootstrap Pattern

Applications typically include graceful shutdown handling:
import { logger } from '@cowprotocol/shared';

async function main() {
  logger.info('Starting service...');

  // Application logic here

  process.on('SIGTERM', async () => {
    logger.info('Shutting down gracefully...');
    // Cleanup logic
    process.exit(0);
  });
}

main().catch((error) => {
  logger.error({ err: error }, 'Fatal error');
  process.exit(1);
});

Shared Libraries

yarn new:lib
Libraries enable code reuse across multiple applications.

Post-Generation Setup

  1. TypeScript path alias - Register in tsconfig.base.json:
{
  "paths": {
    "@cowprotocol/my-library": ["libs/my-library/src/index.ts"]
  }
}
  1. Public API - Define exports in src/index.ts:
export { MyService } from './lib/my-service';
export { MyRepository } from './lib/my-repository';
export type { MyInterface } from './lib/types';
  1. Module boundaries - Follow these rules:
    • Apps can import from libs
    • Libs should only import from other libs
    • Never create circular dependencies

Existing Libraries

The monorepo includes these shared libraries:
LibraryPurpose
@cowprotocol/repositoriesData access layer
@cowprotocol/servicesBusiness logic
@cowprotocol/sharedUtilities and types
@cowprotocol/notificationsNotification templates
@cowprotocol/abisSmart contract ABIs

Architecture Enforcement

NX enforces module boundaries to maintain clean architecture:
  • Apps can import from libs
  • Libs should only import from other libs
  • Circular dependencies are prevented

Pre-Commit Checklist

Before committing changes, run all checks:
# Run tests
yarn test

# Run linter
yarn lint

# Build the project
yarn build
Last modified on March 4, 2026