Open-source monorepo for sending SMS via multiple gateways/providers with a MailHog-style local dev server.
- Multiple Providers - Twilio, MiMSMS, AlphaNet support out of the box
- TypeScript - Full type safety with strict mode
- Transport Pattern - Easily swap between production and mock servers
- Local Dev Server - MailHog-style UI for testing without hitting real APIs
- Docker Ready - Pre-built image available on GitHub Container Registry
# Install dependencies
pnpm install
# Start dev server (API + Web UI)
pnpm dev
# Or run individually
pnpm dev:api # API on http://localhost:3000
pnpm dev:web # Web UI on http://localhost:5173| Package | Version | Description |
|---|---|---|
@smslib/types |
Shared TypeScript interfaces | |
@smslib/core |
SmsClient, FetchTransport | |
@smslib/adapter-twilio |
Twilio SMS adapter | |
@smslib/adapter-mimsms |
MiMSMS SMS adapter | |
@smslib/adapter-alphanet |
AlphaNet SMS adapter |
| App | Description |
|---|---|
dev-server/api |
Express mock server (port 3000) |
dev-server/web |
Vite + React UI (port 5173) |
pnpm build # Build all packages
pnpm test # Run unit tests
pnpm lint # Lint all packages
pnpm typecheck # TypeScript type checking-
CI Workflow (
.github/workflows/ci.yml):- Lint and typecheck
- Unit tests with Vitest
- E2E tests with Playwright
- Build verification
-
Release Workflow (
.github/workflows/release.yml):- Publishes packages to npm via Changesets
- Builds and pushes Docker image to GCR
This repo uses Changesets for version management and npm publishing.
To release a new version:
# Create a changeset (describe what changed)
pnpm changeset
# After merging to main, the release workflow will:
# - Version bump packages
# - Publish to npm
# - Push Docker image to GCRRun the dev server using Docker:
# Pull and run the latest image
docker run -p 3000:3000 ghcr.io/mrmeaow/smslib-server:latest
# The web UI will be available at http://localhost:3000Or use Docker Compose:
services:
smslib:
image: ghcr.io/mrmeaow/smslib-server:latest
ports:
- "3000:3000"Build locally:
docker build -t ghcr.io/mrmeaow/smslib-server:latest apps/dev-server/docker
docker run -p 3000:3000 ghcr.io/mrmeaow/smslib-server:latestsmslib/
├── packages/
│ ├── types/ # Shared interfaces
│ ├── core/ # SmsClient, Transport
│ └── adapters/ # Provider adapters
│ ├── twilio/
│ ├── mimsms/
│ └── alphanet/
├── apps/
│ └── dev-server/
│ ├── api/ # Express mock API
│ ├── web/ # React UI
│ └── docker/ # Dockerfile
└── .github/workflows/ # CI/CD
- Create
packages/adapters/<name>/ - Implement
SmsAdapterinterface from@smslib/types - Add mock endpoints to
apps/dev-server/api/src/routes/ - Add tests and changeset
Adapters use dependency injection for the transport layer:
// Production - uses live URLs
const twilio = new TwilioAdapter({ accountSid: '...', authToken: '...' });
// Development - override transport
const devTransport = new FetchTransport({ baseUrl: 'http://localhost:3000/api' });
const twilio = new TwilioAdapter({ accountSid: '...' }, devTransport);MIT