Guide for AI agents working on the smslib monorepo.
smslib is an open-source monorepo for sending SMS via multiple gateways/providers. It includes a MailHog-style local dev server for testing without hitting real APIs.
| Component | Choice |
|---|---|
| Runtime | TypeScript (strict mode) |
| Monorepo | pnpm workspace + Turbo |
| API Server | Express v5 |
| UI | Vite + React 19 |
| Database | PouchDB (local-first, schema-flexible) |
| Container | Docker |
smslib/
├── packages/
│ ├── types/ # Shared TypeScript interfaces
│ ├── core/ # SmsClient, Transport abstraction
│ └── adapters/
│ ├── twilio/ # International gateway
│ ├── mimsms/ # BD domestic SMS
│ └── alphanet/ # BD domestic SMS
├── apps/
│ └── dev-server/
│ ├── api/ # Express v5 mock endpoints
│ ├── web/ # Vite + React 19 UI
│ └── docker/ # Dockerfile + docker-compose
├── docs/
│ ├── plan.md # Implementation plan
│ └── ref.*.md # Provider API reference docs
├── examples/
├── turbo.json
├── pnpm-workspace.yaml
└── package.json
- Transport decides environment - base URL is injected via Transport, not adapter
- Adapters stay unaware of environment - no
if (dev)inside adapters - Dev server mimics real provider APIs - adapter code stays identical between dev/prod
- Each adapter is a separate package - incrementally addable
- Publishable packages -
packages/*are intended for npm publishing (public use)
Adapters use these URLs by default when no custom transport is provided:
| Provider | Base URL |
|---|---|
| Twilio | https://api.twilio.com/2010-04-01 |
| MiMSMS | https://api.mimsms.com |
| AlphaNet | https://api.sms.net.bd |
# Install dependencies
pnpm install
# Run dev server (API + Web)
pnpm dev
# Run only API
pnpm dev:api
# Run only Web UI
pnpm dev:web
# Build all packages
pnpm build
# Lint all packages
pnpm lint- Create
packages/adapters/<name>/package - Implement
SmsAdapterinterface from@smslib/types - Add mock endpoints to
apps/dev-server/api/src/routes/<name>.ts - Update
docs/plan.mdwith new provider info
interface SmsAdapter {
readonly provider: string;
send(msg: SmsMessageCreate): Promise<SendResult>;
getName(): string;
}Adapters default to live URLs. Override via transport for dev:
// Production - adapter creates default transport with live URL
const twilio = new TwilioAdapter({ accountSid: 'AC...', authToken: 'xxx' });
// → internally uses FetchTransport('https://api.twilio.com/2010-04-01')
// Development - override transport baseUrl
const devTransport = new FetchTransport({ baseUrl: 'http://localhost:3000/api' });
const twilio = new TwilioAdapter(
{ accountSid: 'AC...', authToken: 'xxx' },
devTransport
);{
"dev": "pnpm --filter dev-server dev",
"dev:api": "pnpm --filter dev-server/api dev",
"dev:web": "pnpm --filter dev-server/web dev",
"build": "turbo build",
"lint": "turbo lint"
}- Target: ES2022
- Module: NodeNext
- ModuleResolution: NodeNext
- Strict mode enabled
Each adapter accepts:
config- provider-specific credentialstransport- HTTP transport with configurable base URL
The adapter only knows the endpoint path (e.g., /Messages.json), while the transport handles the full URL (e.g., http://localhost:3000/api/Messages.json).
| Route | Provider | Mimics |
|---|---|---|
POST /api/twilio/messages |
Twilio | Twilio API |
POST /api/mimsms/send |
MiMSMS | MiMSMS API |
POST /api/alphanet/sendsms |
AlphaNet | AlphaNet API |
GET /api/messages |
- | Message listing |
GET /api/messages/:id |
- | Message detail |
- TypeScript source:
src/index.ts - React components:
PascalCase.tsx - Utilities:
camelCase.ts - Route handlers:
kebab-case.ts - Test files:
*.test.tsor*.spec.ts
Use workspace:* for internal package dependencies:
{
"dependencies": {
"@smslib/types": "workspace:*"
}
}Packages under packages/* are intended for public npm publishing.
Each publishable package must have:
name:@smslib/<package-name>version: Semver format (e.g.,0.1.0)type:"module"license:"MIT"or similardescription: Brief descriptionrepository: Link to git repoexports: Proper ESM export mappingmain: CJS fallback (.js)types: TypeScript declaration (.d.ts)
{
"name": "@smslib/adapter-twilio",
"version": "0.1.0",
"type": "module",
"license": "MIT",
"description": "Twilio SMS adapter for smslib",
"repository": "https://github.com/mrmeaow/smslib",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"files": ["dist"]
}During development, use workspace:*:
"dependencies": {
"@smslib/types": "workspace:*"
}When publishing, these will be replaced with actual version ranges.