Migrating from node-smpp
API mapping and behavior changes for existing node-smpp users.
better-smpp is byte-compatible with node-smpp on the wire, so you can migrate one side of a connection at a time. The API is a redesign: Promises instead of callback triples, typed PDUs, and explicit client/server packages.
Client mapping
| node-smpp | better-smpp |
|---|---|
smpp.connect('smpp://user:pass@host', cb) | const client = new SmppClient({ url }); await client.connect() |
session.bind_transceiver({...}, cb) | await client.bindTransceiver({...}) — throws SmppCommandError on failure |
session.submit_sm({...}, cb) + status check | await client.submitSm({...}) — rejects on non-ESME_ROK |
session.on('deliver_sm', pdu => session.send(pdu.response())) | client.on("message"/"receipt", …) — acked automatically |
auto_enquire_link_period | enquireLink: { intervalMs } — now with dead-link detection |
manual session.connect() to reopen | reconnect: true — backoff + rebind, lifecycle events |
session.on('connect') | client.on("connect" / "bound") |
pdu.response({...}) | createResponse(pdu, {...}) or client.respond(pdu, {...}) |
Server mapping
| node-smpp | better-smpp |
|---|---|
smpp.createServer(opts, listener) | new SmppServer(opts, listener) |
server.listen(2775) | await server.listen({ port: 2775 }) |
bind event + pause()/resume() + manual resp | onBind: async (session, pdu) => verdict |
session.deliver_sm({...}, cb) | await session.deliverSm({...}) |
{ key, cert } at top level | tls: { key, cert } |
enable_proxy_protocol_detection (proxywrap) | proxyProtocol: true — native parser |
smpp.addCommand / smpp.addTLV (global) | new SmppRegistry().registerCommand(...) via the registry option |
Field names
Body fields and TLVs are the camelCase form of the spec names — a mechanical
rename: source_addr → sourceAddr, short_message → shortMessage,
esm_class → esmClass, command_status → commandStatus. Command names stay
snake_case (submit_sm) as protocol identifiers and event names.
Constants moved from flat exports to namespaced ones:
// before // after
smpp.ESME_ROK CommandStatus.ESME_ROK
smpp.TON.INTERNATIONAL TON.INTERNATIONAL
smpp.ENCODING.UCS2 DATA_CODING.UCS2
smpp.consts.REGISTERED_DELIVERY REGISTERED_DELIVERYBehavior changes to review
- TLS certificates are verified by default. node-smpp silently set
rejectUnauthorized: false. Passtls: { rejectUnauthorized: false }explicitly for self-signed peers. - Failed requests reject with
SmppCommandError(carrying.commandStatusand.response) instead of returning a response object to inspect. - Every request times out (default 30 s, configurable per call). node-smpp waited forever and leaked its callback map.
submitSmmay send several PDUs. Over-length text splits automatically; the result aggregates segment responses.concatenation: falserestores send-as-is.deliver_smis auto-acknowledged around themessage/receiptevents. SetautoAckDeliverSm: falseto respond manually.debug/debugListenerare gone — passloggerandmetricshooks instead.
What you get for free
Automatic long-message concatenation and reassembly, structured delivery receipts,
send windows, throttle backoff, congestionState tracking, reconnect + rebind,
dead-link detection, AbortSignal support, and the full typed v5.0 broadcast family.