Pick packages by problem
A map from the task in front of you to the packages that solve it and the guide that puts them to work, grouped by the kind of work rather than by package.
Last updated
After reading this guide, you will know
- What package solves the task in front of you
- Where the guide that composes those packages is
- What else a package usually arrives with, so you install them together
You know the problem and want the package. Each table below starts from a task, names the packages that solve it, and links the guide that puts them to work. The packages in one row are installed together, at one release, as Install and pin describes, and every package missing here is listed on the API reference.
Handle failures and validate input
| I need to… | Packages | Guide |
|---|---|---|
| return failures as values instead of throwing | @sdxc/result | Result everywhere |
| validate form posts, query strings and route params | @sdxc/validate | Validate forms and route params |
| answer a failure as an RFC 9457 problem document | @sdxc/problem | Errors as responses |
Answer HTTP requests
| I need to… | Packages | Guide |
|---|---|---|
| answer JSON with a named status, outside any framework | @sdxc/response | Use the packages outside Remix |
| set cache headers on a response in a Remix app | @sdxc/http | Cache on Cloudflare Workers |
| redirect to one canonical host and path | @sdxc/no-www-middleware, @sdxc/trailing-slash-middleware | Canonical URLs, lazy routes and header fields |
| read the caller's IP address and classify it | @sdxc/get-client-ip, @sdxc/ip | Client addresses and networks |
| fetch a URL someone else chose, within bounds | @sdxc/outbound | Fetch URLs a stranger chose |
Build an API
| I need to… | Packages | Guide |
|---|---|---|
| build a JSON API that answers failures as problems | @sdxc/problem, @sdxc/http | Build a JSON API with problem details |
| page a list by offset or keyset | @sdxc/pagination, @sdxc/link-header | Paginate lists |
| limit how often a caller may ask | @sdxc/rate-limit | Client addresses and networks |
| describe the API as an OpenAPI 3.1 document | @sdxc/openapi, @sdxc/json-schema | Describe your API with OpenAPI |
| make a create safe to retry, accept partial updates | @sdxc/idempotency, @sdxc/merge-patch | Idempotent writes and JSON Merge Patch |
| write a typed client for someone else's API | @sdxc/api-client | Write a typed API client |
| expose the app to AI agents over MCP | @sdxc/mcp | Expose your app over MCP |
| call a Streamable HTTP MCP endpoint from code | @sdxc/mcp | Call an MCP server |
| point handshake-era agents at a modern-only MCP URL | @sdxc/mcp | Bridge Agents to a modern MCP server |
Sign people in and decide what they may do
| I need to… | Packages | Guide |
|---|---|---|
| sign people in with an OpenID Connect provider | @sdxc/auth, @sdxc/session-storage-kv | Sign in with OpenID Connect |
| issue and verify JWTs and publish a JWKS | @sdxc/jwt | Issue and verify JWTs |
| add passkeys | @sdxc/passkey | Add passkeys |
| add TOTP two-factor sign-in | @sdxc/crypto, @sdxc/qr | Add two-factor sign-in with TOTP |
| decide who can do what | @sdxc/authz | Decide who can do what |
| mint record ids, random identifiers and secrets | @sdxc/uuid, @sdxc/typeid, @sdxc/crypto | Identifiers and secrets |
Secure the app
| I need to… | Packages | Guide |
|---|---|---|
| hash, sign and encrypt with Web Crypto | @sdxc/crypto | Hash, sign and encrypt with Web Crypto |
| send CSP, HSTS and Permissions-Policy headers | @sdxc/security-headers | Security headers and CSP |
| receive and send signed webhooks | @sdxc/webhooks | Receive and send webhooks |
| stop bots on a public form | @sdxc/honeypot, @sdxc/captcha | Protect forms from bots and abuse |
| score submitted content for spam | @sdxc/spam | Protect forms from bots and abuse |
Publish content
| I need to… | Packages | Guide |
|---|---|---|
| parse markdown with typed frontmatter and render it | @sdxc/markdown | A markdown content pipeline |
| highlight code blocks | @sdxc/highlight | A markdown content pipeline |
| publish RSS, Atom and JSON feeds | @sdxc/feed, @sdxc/rss, @sdxc/atom, @sdxc/json-feed | Publish RSS, Atom and JSON feeds |
serve a sitemap, robots.txt and structured data | @sdxc/sitemap, @sdxc/robots, @sdxc/seo | SEO, sitemaps and robots.txt |
Read and write file formats
| I need to… | Packages | Guide |
|---|---|---|
| import and export CSV | @sdxc/csv | Import and export CSV |
| stream JSON Lines | @sdxc/jsonl | Stream JSON Lines |
| bundle several files into one ZIP download | @sdxc/zip | Stream several files as a ZIP |
publish calendar feeds and read .ics uploads | @sdxc/icalendar | Publish calendar feeds |
| write invoices and reports as PDF | @sdxc/pdf | Generate PDF documents |
Build the interface
| I need to… | Packages | Guide |
|---|---|---|
| compose pages from styled components | @sdxc/ui, @sdxc/u, @sdxc/icons | Build the interface with remix/component |
| translate the app | @sdxc/i18n, @sdxc/messageformat | Translate your app |
| slug titles, format dates, compare versions | @sdxc/strings, @sdxc/dates, @sdxc/semver | Dates, text and identifiers |
| draw social card images in a Worker | @sdxc/png, @sdxc/font, @sdxc/raster | Draw social card images |
| draw QR codes | @sdxc/qr | Draw QR codes |
Store data
| I need to… | Packages | Guide |
|---|---|---|
| query D1 or a Durable Object's SQLite | @sdxc/data-table-d1, @sdxc/data-table-sqlstorage, @sdxc/database-middleware | Query D1 and Durable Object SQL |
| model tables with scopes and callbacks | @sdxc/data-model | Model your tables |
| cache values in KV and responses at the edge | @sdxc/cache, @sdxc/workers-cache | Cache on Cloudflare Workers |
| store uploads in R2 | @sdxc/file-storage-r2 | Accept PNG avatars and draw placeholders |
| search text over SQLite | @sdxc/search | Full-text search over SQLite |
| roll out features behind flags | @sdxc/flags, @sdxc/flags-engine | Feature flags |
| charge for the app | @sdxc/billing | Charge for your app |
Run work in the background and reach people
| I need to… | Packages | Guide |
|---|---|---|
| run background jobs and cron schedules | @sdxc/jobs, @sdxc/cron | Background jobs and cron |
| retry on a growing delay | @sdxc/backoff | Retry on a growing delay |
| send email | @sdxc/mail | Send email |
| send alerts to chat and paging services | @sdxc/messaging | Send alerts to chat and paging services |
Operate and test
| I need to… | Packages | Guide |
|---|---|---|
| log one wide event per request and trace into jobs | @sdxc/logger, @sdxc/trace-context, @sdxc/server-timing | Logs, traces and timings |
answer GET /health for monitors | @sdxc/health | Dependency health checks |
| build a command line | @sdxc/cli | Build a command line |
| test against Cloudflare bindings in memory | @sdxc/cloudflare-mocks | Test Workers apps |
| generate believable, repeatable test data | @sdxc/sample, @sdxc/random | Generate believable test data |
| start, generate and upgrade a whole app | @sdxc/kit | The sdxc command |
Where to go next
Use the packages outside Remix — which of these run with no framework, and how to tell from a package's page.
Add packages to an existing app — install the packages you picked into the project you have, pinned at one release.
@sdxcAPI reference — every package, grouped, with its install line.