Create Next.js adapter package
Summary
Create @universal-data-layer/adapter-nextjs, the first adapter package that exposes a udl-next CLI as a drop-in replacement for next commands, running both UDL and Next.js together.
Context
Component: New package packages/adapter-nextjs/
Estimated Time: 2-3 days
Priority: Medium
Problem Statement
Currently, developers must run UDL and Next.js in separate terminals or use shell concurrency:
"scripts": {
"dev": "udl & next dev", // Manual concurrency
"udl": "universal-data-layer"
}
The adapter provides a cleaner solution:
"scripts": {
"dev": "udl-next dev",
"build": "udl-next build",
"start": "udl-next start"
}
Technical Specification
CLI Commands
| Command |
Behavior |
udl-next dev |
Run universal-data-layer + next dev concurrently |
udl-next build |
Start UDL server, run codegen, then run next build |
udl-next start |
Run universal-data-layer + next start concurrently |
Implementation Approach
Create a new package using native child_process (no external dependencies):
- Parse subcommand (
dev, build, start)
- For
dev/start: spawn both processes concurrently with prefixed output
- For
build: start UDL, wait for ready, run codegen, run next build, cleanup
- Prefix output lines with
[udl] and [next] for clarity
- Handle graceful shutdown (SIGINT/SIGTERM kills both)
- If either process exits unexpectedly, terminate the other and exit
Files to Create
packages/adapter-nextjs/package.json - Package manifest with bin config
packages/adapter-nextjs/bin/udl-next.js - CLI entry point
packages/adapter-nextjs/src/cli.ts - CLI arg parsing and command routing
packages/adapter-nextjs/src/commands/dev.ts - Dev command (concurrent)
packages/adapter-nextjs/src/commands/build.ts - Build command (sequential)
packages/adapter-nextjs/src/commands/start.ts - Start command (concurrent)
packages/adapter-nextjs/src/utils/spawn.ts - Process spawning utilities
packages/adapter-nextjs/src/utils/prefix-output.ts - Output prefixing
packages/adapter-nextjs/tsconfig.json - TypeScript config
packages/adapter-nextjs/README.md - Usage documentation
Files to Modify
examples/nextjs/package.json - Update scripts to use udl-next
Key Interfaces
// src/utils/spawn.ts
import { spawn, ChildProcess } from 'node:child_process';
interface SpawnedProcess {
process: ChildProcess;
name: string;
prefix: string;
}
function spawnWithPrefix(
command: string,
args: string[],
prefix: string
): SpawnedProcess;
function killAll(processes: SpawnedProcess[]): void;
// src/cli.ts - CLI structure
// udl-next dev [--port <udl-port>] [--next-port <port>]
// udl-next build [--port <udl-port>]
// udl-next start [--port <udl-port>] [--next-port <port>]
// udl-next --help
Package.json Configuration
{
"name": "@universal-data-layer/adapter-nextjs",
"version": "1.0.0",
"type": "module",
"bin": {
"udl-next": "bin/udl-next.js"
},
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist", "bin", "README.md"],
"peerDependencies": {
"universal-data-layer": "^1.0.0",
"next": ">=14.0.0"
}
}
Note: No runtime dependencies - uses native child_process.
Implementation Tasks
Acceptance Criteria
Testing Requirements
Unit Tests
- Test CLI arg parsing for each subcommand
- Test output prefixing logic
- Test graceful shutdown handling
- Test "kill both" behavior when one exits
Integration Test
- Spawn
udl-next dev, verify both servers start, send SIGINT, verify both stop
Dependencies
- Blocked by: None
- Related to: Next.js example at
examples/nextjs/
Notes
- Uses native
child_process - no external dependencies
- Follow existing CLI patterns from
packages/core/bin/cli.js
- This is the first "adapter" package, establishing the pattern for future adapters (Remix, Astro, etc.)
Create Next.js adapter package
Summary
Create
@universal-data-layer/adapter-nextjs, the first adapter package that exposes audl-nextCLI as a drop-in replacement fornextcommands, running both UDL and Next.js together.Context
Component: New package
packages/adapter-nextjs/Estimated Time: 2-3 days
Priority: Medium
Problem Statement
Currently, developers must run UDL and Next.js in separate terminals or use shell concurrency:
The adapter provides a cleaner solution:
Technical Specification
CLI Commands
udl-next devuniversal-data-layer+next devconcurrentlyudl-next buildnext buildudl-next startuniversal-data-layer+next startconcurrentlyImplementation Approach
Create a new package using native
child_process(no external dependencies):dev,build,start)dev/start: spawn both processes concurrently with prefixed outputbuild: start UDL, wait for ready, run codegen, run next build, cleanup[udl]and[next]for clarityFiles to Create
packages/adapter-nextjs/package.json- Package manifest with bin configpackages/adapter-nextjs/bin/udl-next.js- CLI entry pointpackages/adapter-nextjs/src/cli.ts- CLI arg parsing and command routingpackages/adapter-nextjs/src/commands/dev.ts- Dev command (concurrent)packages/adapter-nextjs/src/commands/build.ts- Build command (sequential)packages/adapter-nextjs/src/commands/start.ts- Start command (concurrent)packages/adapter-nextjs/src/utils/spawn.ts- Process spawning utilitiespackages/adapter-nextjs/src/utils/prefix-output.ts- Output prefixingpackages/adapter-nextjs/tsconfig.json- TypeScript configpackages/adapter-nextjs/README.md- Usage documentationFiles to Modify
examples/nextjs/package.json- Update scripts to useudl-nextKey Interfaces
Package.json Configuration
{ "name": "@universal-data-layer/adapter-nextjs", "version": "1.0.0", "type": "module", "bin": { "udl-next": "bin/udl-next.js" }, "main": "dist/index.js", "types": "dist/index.d.ts", "files": ["dist", "bin", "README.md"], "peerDependencies": { "universal-data-layer": "^1.0.0", "next": ">=14.0.0" } }Note: No runtime dependencies - uses native
child_process.Implementation Tasks
package.jsonbin/udl-next.jsCLI entry pointdev,build,start)spawnWithPrefixutility for prefixed outputdevcommand (concurrent UDL + next dev)startcommand (concurrent UDL + next start)buildcommand (sequential: UDL → codegen → next build)examples/nextjs/package.jsonscriptsAcceptance Criteria
udl-next devstarts both UDL and Next.js dev servers concurrentlyudl-next buildruns codegen then next buildudl-next startruns both UDL and Next.js production servers[udl]and[next]prefixes--helpshows usage informationTesting Requirements
Unit Tests
Integration Test
udl-next dev, verify both servers start, send SIGINT, verify both stopDependencies
examples/nextjs/Notes
child_process- no external dependenciespackages/core/bin/cli.js