Client library
The JavaScript/TypeScript client is published as @rendorix/client. There is no browser bundle for signing: it is a server-only package that turns object keys and transform options into HMAC-signed CDN URLs for <img src="…"> and srcset.
“Tailwind for images”
Section titled ““Tailwind for images””If Tailwind is “utility CSS from a shared config,” @rendorix/client is “utility image URLs from a shared preset map”:
- You declare
hero,card,avatar(and theirw/h/f/q) once increateRendorix({ presets })—the single source of truth for how “hero” looks in pixels and format. - In server templates, loaders, and API handlers you write
img("photos/team.jpg", { preset: "hero" })—no hand-built query strings, no sorting keys for HMAC, no wiringexpandsin every file. - Optional overrides (
w,h,f,q) tweak a preset for one call, the same way you override a single utility class in markup.
The browser only sees the finished URL; the secret never leaves the server. See Security and Rendering strategies.
Package layout (repository)
Section titled “Package layout (repository)”Paths below are from the package / repository root where @rendorix/client is developed (see the Rendorix project on GitHub). Adjust if your monorepo nests the package under packages/client or similar.
| Path | Role |
|---|---|
package.json | Package name @rendorix/client, exports, build / prepare (tsup), test (vitest). |
tsup.config.ts | Bundles src/index.ts to ESM + CJS, generates .d.ts, platform: "node", target ES2022. |
src/index.ts | Public API: createRendorix, RendorixError, and type re-exports. |
src/createRendorix.ts | Factory that returns the img() function; validation, canonicalization, signing. |
src/types.ts | Transform, Presets, RendorixConfig, ImgOptions, Format. |
src/resolve.ts | Merges preset + inline overrides into a single Transform. |
src/validate.ts | Bounds for w, h, q, and allowed f values. |
src/canonicalize.ts | Query string and signing string (must match the CloudFront Function). |
src/sign.ts | HMAC-SHA256 with Node node:crypto. |
src/errors.ts | RendorixError with typed code. |
test/ | Vitest per module, integration tests (e.g. signing parity). |
Build output goes to dist/ (generated by npm run build or prepare on install; often not committed).
Mental model
Section titled “Mental model”- Input — S3-style object key (e.g.
photos/hero.jpg) and options:preset, overrides (w,h,f,q), optional per-callttl. - Resolve — If
presetis set, look it up and merge inline fields on top (overrides win). - Validate — Dimensions, quality, format in allowed ranges.
- Canonicalize — Query string with transform params and
exp(Unix), keys sorted. Signing string:path + "?" + queryWithoutS(nosyet). - Sign —
s= hex HMAC-SHA256 of the signing string. - Output —
baseUrl + path + "?" + query + "&s=" + sig. CloudFront validatessandexp, then may strip or normalize for cache/origin per your deployment.
With a typed presets object, preset: "…" is checked at compile time (typos are errors).
Public API
Section titled “Public API”createRendorix(config)
Section titled “createRendorix(config)”RendorixConfig (see src/types.ts in the package):
| Field | Description |
|---|---|
baseUrl | CloudFront (or image) origin; trailing slashes normalized. Bad URL → RendorixError invalid_config at factory time. |
secret | HMAC key (non-empty). Missing/invalid → invalid_config at factory time. |
presets | Optional preset → Transform map. Empty/omitted means only raw w/h/f/q (no preset option). |
defaultTtl | URL lifetime in seconds, default 30 days. |
Returns a RendorixClient with:
img(key, opts?)— synchronous; returns a signed URL string.
img(key, opts?)
Section titled “img(key, opts?)”- Key — Leading slashes stripped; path in the URL is
/${cleanKey}. ImgOptions—preset(must exist inpresetsorunknown_preset), optionalw,h,f,q(override preset), optionalttl(seconds; overridesdefaultTtlfor that call only).- Expiry —
exp = floor(Date.now() / 1000) + ttl(per package behavior).
RendorixError codes — unknown_preset, invalid_dimension, invalid_quality, invalid_format, invalid_config (mainly from createRendorix).
Module behavior (summary)
Section titled “Module behavior (summary)”- Types —
Formatisjpeg|jpg|webp|png|avif.Transformholds optionalw,h,f,q(notexp/s). - Resolve — With
preset, mergepresets[preset]with inline options (withoutttl).ttlonly affectsexp, not the transform merge. - Validate —
w/h: integers 1…4096;q: 1…100;fmust be allowed (includes bothjpegandjpg). Omitted fields are not validated. - Canonicalize — Only defined transform fields and
exp; keys sorted (e.g.localeCompare).sis not part of the string being signed. Must stay aligned with the CloudFront viewer-request code (e.g.cloudfront-function/signertemplate in the infra repo). - Sign —
createHmac("sha256", secret).update(signingString).digest("hex")(lowercase hex, 64 chars).
Build and distribution
Section titled “Build and distribution”- tsup →
dist/index.mjs,dist/index.cjs,dist/index.d.ts(+ source maps). prepare— Often runstsuponnpm installfor Git/gitpkg consumers.- Engines —
node >= 18; usesnode:crypto.
How it fits the stack
Section titled “How it fits the stack”- This package — Mints signed URLs.
- CloudFront Function — Validates signatures and may normalize query params for cache keys.
- Lambda (image worker) — Performs transforms; not called from this client directly.
For key rotation, Terraform can provide two secrets to the CloudFront Function so old and new URLs verify during a window; the client only needs the current secret for new URLs. See Security and Deployment.
Testing
Section titled “Testing”npm test (Vitest) covers canonicalization order, validation edge cases, preset merge, and signing parity with CloudFront rules where applicable. Run from the package directory in the Rendorix repo.
See also
Section titled “See also”- Usage: Generating image URLs — conceptual flow (now implemented by this package where you adopt it)
- Examples — Astro and other app wiring
- HMAC signing — must match the edge verifier byte-for-byte