NJ Municipality Lookup
CodebaseExamples

Extracting Domain

These examples show how to use the NJ address domain in different application contexts.

Extracting Domain for Use in Other Projects

These examples show how to use the NJ address domain in different application contexts.

Approaches

Approach 1: Copy Files

The simplest approach - copy the domain layer into your project:

# Copy domain to your project
cp -r src/domain your-project/src/nj-address-domain

# Copy adapters you need
cp -r src/adapters/nj-api your-project/src/adapters/nj-api
cp -r src/adapters/cache your-project/src/adapters/cache
cp -r src/adapters/http your-project/src/adapters/http

Benefits:

  • Full control over the code
  • No external dependency
  • Can modify as needed

Trade-offs:

  • Manual updates when original changes
  • Need to copy dependencies

Approach 2: Use as Dependency (with exports)

If this package is available as a dependency:

# Install as dependency
bun add nj-municipality-lookup

# Or from git
bun add github:newjersey/business-address-lookup

Then import:

// Import domain entities and use cases
import { createAddressInput } from "nj-municipality-lookup/domain";
import { createLookupAddressUseCase } from "nj-municipality-lookup/domain";

// Import adapters
import { createNjGeocodingClient } from "nj-municipality-lookup/adapters";
import { createInMemoryCache } from "nj-municipality-lookup/adapters";

Benefits:

  • Easy updates
  • Smaller codebase
  • Shared maintenance

Examples

1. Express API (express-api-example.ts)

Using the domain in an Express.js API.

What it demonstrates:

  • Integrating with different web frameworks
  • Setting up services in Express middleware
  • Sharing adapters across requests
  • Error handling in REST APIs

2. CLI Tool (cli-tool-example.ts)

Using the domain in a command-line tool.

What it demonstrates:

  • Using domain in non-web contexts
  • Progress reporting
  • File I/O integration
  • Batch processing

3. React Hook (react-hook-example.tsx)

Using the domain in a React application (different from Next.js).

What it demonstrates:

  • Client-side integration
  • Custom hooks
  • State management
  • Error boundaries

What to Extract

Minimum Required:

  • src/domain/ - All domain logic (entities, use cases, ports, errors)

Commonly Needed:

  • src/adapters/nj-api/ - NJ API integration
  • src/adapters/http/ - HTTP client
  • src/lib/validation.ts - Input validation
  • src/lib/logger.ts - Logging

Optional:

  • src/adapters/cache/ - If you need caching
  • Test helpers from src/__tests__/helpers/ - For testing

Framework Independence

The domain layer has zero dependencies on:

  • Next.js
  • React
  • Any specific web framework
  • Node.js-specific APIs

It uses only:

  • TypeScript standard library
  • Pure JavaScript features
  • Standard Promises
  • Standard Error handling

This means it works in:

  • Node.js
  • Bun
  • Deno
  • Browser (with bundler)
  • Cloudflare Workers
  • AWS Lambda
  • Any JavaScript runtime

Dependencies

The domain itself has no external dependencies. The adapters require:

NJ API Adapter:

  • HTTP client (can be any implementation of HttpClientPort)

Cache Adapter:

  • None (in-memory)
  • Or Redis client (if using Redis adapter)

Validation:

  • None (uses built-in JavaScript)

Integration Steps

  1. Copy or install the domain code
  2. Set up adapters with your HTTP client and dependencies
  3. Create use cases by wiring adapters together
  4. Use in your application layer (API routes, React components, CLI, etc.)

See individual example files for implementations.

On this page