Open source · MIT licensed · free forever

Real SMS. Zero Twilio.
Your Phone Powers It Up.

simwire pairs your Android phone with your code. Send and receive real texts from Node.js with no accounts, no per-message fees, and nothing in between.

Start building free

Set up your phone

Step 1 of 4. About two minutes.
  • Install the simwire app
  • Scan the QR from your terminal
  • LAN handshake, token stays local
  • Send your first SMS

Live delivery

to +1 555 014 2834 · SIM 1
Queued on device0.1s ✓
Sent by SIM0.6s ✓
Delivered to handsetwaiting…
Cost$0.00

Incoming stream

Forwarded to localhost:3000/sms
+1 555 019 0000 · "Your code is 428113"200
ACME BANK · "You received $250.00"200
ACME BANK · "You received $1,120.00"200
3 events · no public webhook, no tunnel

Mock suite passed

8/8 tests · 0.4s · no phone needed
sms.outbox assertions
simulateIncoming()
forced failures
NODE.JS TypeScript android npm WebSocket vivitest
$0 / msg
Your SIM, your plan. No per-message pricing.
0 min
From npm install to a delivered SMS.
0
Accounts, API keys, compliance forms.
0%
On your LAN. Nothing leaves your network.
How it works

Terminal to SIM in three steps

No dashboard, no API keys, no billing form. Your terminal and your phone.

$ npx simwire pair
Scan with the simwire app…
Paired with Pixel 8 (2 SIM slots)
Token saved to ~/.simwire
1

Pair your phone once

Install the app, run npx simwire pair and scan the QR. The token never leaves your two devices.

2

Send from your code

Call sms.send() and get real carrier statuses back: queued, sent, delivered. As promises or events.

3

Receive on localhost

Incoming SMS stream to your machine over the LAN, or straight into your local server with simwire listen.

Features

Built for the way you actually develop

Everything you keep rebuilding around SMS APIs, in the box.

Receive on localhost

Your phone pushes every incoming SMS to your dev machine over WebSocket. OTP flows become testable end-to-end, offline.

+15550190000  "Your code is 428113"
ACME BANK  "You received $250.00"
POST localhost:3000/sms  200

Statuses that mean something

Not just accepted by an API. Actually sent by the SIM, actually delivered to the handset. As events, or awaited.

queuedsentdelivered

Mock device for CI

Same API, no hardware. Outbox assertions, simulated incoming, forced failures.

const sms = mock(); 8 tests  0.4s

Dual-SIM routing

Pick the SIM per message: OTPs on one carrier, alerts on the other.

SIM 1Work
SIM 2Personal

simwire doctor

One command that says why it's not working, with the fix.

paired · Pixel 8
mDNS discovery
battery optimization → fix

Durable queue

Messages persist on the phone before they're accepted. A killed app restarts and resumes exactly where it left off.

An open protocol, not a silo

Plain WebSocket frames, documented pairing, mDNS discovery. Build your own client in an afternoon.

_simwire._tcp · :4650 · JSON frames
The SDK

An API that feels like it was always there

TypeScript-first, promise-based, event-driven. One import for production, one for tests.

import { connect } from "simwire";

const sms = await connect();            // finds your phone on the LAN

const msg = await sms.send({
  to: "+15550142834",
  text: "Your code is 4821",
});

await msg.waitForDelivery();            // real carrier status
sms.on("message", (m) => {
  if (m.text.startsWith("BANK:")) reconcilePayment(m);
});

// or pipe straight into your local server:
// $ npx simwire listen --forward http://localhost:3000/sms
import { mock } from "simwire";

const sms = mock();                     // no phone, same API

await sms.send({ to: "+15550100000", text: "OTP: 1234" });
expect(sms.outbox).toHaveLength(1);

sms.simulateIncoming({ from: "+15550100001", text: "STOP" });
Compare

Renting an SMS API can wait

For development, testing and transactional volume, the phone in your pocket wins.

simwireTwilio & friends
Price per SMSYour plan, usually free$0.008 to 0.05, plus number rental
Setup2 min, one QR scanAccount, billing, compliance forms
Receive in local devNative, streams to localhostPublic webhook plus tunnel
Test storyBuilt-in mock deviceMagic numbers, third-party mocks
Data pathStays on your LANVendor cloud
Bulk campaignsNo, by designYes, that's their job
Honest positioning: simwire is for development, testing and small transactional volume: OTPs, alerts, payment confirmations. Carriers throttle and ban SIMs that spam. If you need ten thousand messages an hour, rent a shortcode.

Two minutes from npm install
to a delivered text.

Open source, MIT licensed, yours to keep.