Getting Started
1What do I need before starting setup?
You need a short domain using Cloudflare DNS, a GitHub account and repository, a Cloudflare account, Git, Node.js 20 or newer, npm, and a text editor. After cloning, the normal path is
npm run detach, npm install, npm run setup, npm run local-install, and npm run check.operator
high priority
Evidence
- vanityURLs/code
README.md— Quickstart lists a registered short domain, GitHub and Cloudflare accounts, Git, Node.js 20+, npm, and a text editor. - vanityURLs/code
package.json— Project scripts include setup, local-install, check, and deploy workflows.
Related:
hosted-service, worker-deployment
Architecture
7How does vanityURLs work without a database?
vanityURLs compiles link and policy source files into static runtime JSON that the Cloudflare Worker reads from the Static Assets binding. There is no account database or mutable click store in the default runtime; Git is the system of record.
operator
contributor
high priority
Evidence
- vanityURLs/code
README.md— Links, schedules, destination policies, localized pages, and operator configuration live in Git. - vanityURLs/code
scripts/build.mjs— Build writes build/v8s.json, build/v8s-blocklist.json, build/v8s-site-config.json, and build/v8s-custom-assets.json for the Worker.
Is vanityURLs a hosted URL shortener like Bitly, Short.io, or Dub?
No. vanityURLs is open-source software for running your own branded short-link instance on your Cloudflare account and domain. The public docs site is not a shared link-shortening service.
operator
end-user
high priority
Evidence
- vanityURLs/code
README.md— Quickstart instructs operators to clone the code, configure their own domain, and deploy their own Worker.
Related:
setup-prerequisites, who-operates-instance
What is build/v8s.json?
build/v8s.json is the generated runtime link registry consumed by the Worker. Humans edit the source link registry in custom/v8s-links.txt; the build validates that source and compiles it into this runtime JSON. Treat build/v8s.json as generated output, not hand-edited source.operator
contributor
high priority
Evidence
- vanityURLs/code
scripts/build.mjs— buildRedirectTargets writes the generated runtime link registry, build/v8s.json, from custom/v8s-links.txt or defaults/v8s-links.txt. - vanityURLs/code
scripts/validate-runtime-registry.mjs— Runtime link registry schema 3.1 validates links, routing, states, and tree shape.
Why does vanityURLs use Node.js if it runs on Cloudflare Workers?
Node.js is used for local tooling: setup prompts, builds, validation, tests, and helper commands. The deployed redirector runs on the Cloudflare Workers serverless platform, which executes JavaScript at the edge. The same language family lets the project share validation and build conventions across Linux, macOS, Windows, and Cloudflare Workers without shipping a native server process.
operator
contributor
medium priority
Evidence
- vanityURLs/code
package.json— Project scripts run setup, build, tests, local helper install, and maintenance commands with Node. - vanityURLs/code
wrangler.toml— The deployed runtime is a Cloudflare Worker generated from source under scripts/workers/.
Are commands like lnk and v8s-fix real CPU-specific binaries?
They are executable scripts, not compiled CPU-specific binaries. The shebang asks the operating system to launch
node, then Node runs the text file. You do not need separate Apple Silicon, Intel, Linux, or Windows builds; you need a compatible Node.js runtime and the script file copied with executable permissions on Unix-like systems.operator
contributor
medium priority
Evidence
- vanityURLs/code
scripts/lnk— The command starts with#!/usr/bin/env node. - vanityURLs/code
scripts/v8s-fix— The command is an executable Node wrapper for the maintenance implementation. - vanityURLs/code
scripts/local-install.mjs— Local install copies executable scripts into the configured user bin directory.
What does the .mjs file extension mean?
.mjs marks a JavaScript file as an ES module. ES modules use import and export syntax and match the module style used by modern Node.js tooling and Cloudflare Workers. In vanityURLs, .mjs files are still JavaScript; the extension mainly makes the module format explicit.operator
contributor
medium priority
Evidence
- vanityURLs/code
package.json— The package declarestype: module, and most project scripts use ES module syntax. - vanityURLs/code
scripts/build.mjs— Build tooling imports Node modules and project helpers with ES moduleimportsyntax. - vanityURLs/code
scripts/workers/worker.mjs— The Worker source is also an ES module.
Which HTTP methods does the Worker accept?
Public redirect and page requests use
GET or HEAD; OPTIONS receives a quiet 204. Other methods return 405 Method not allowed, with POST /lookup/resolve reserved for lookup resolution and POST /_analytics/lookup reserved for the lookup-page beacon. Sandboxed custom HTML can call those two public lookup endpoints with Origin: null; protected endpoints remain locked down.operator
contributor
trust-safety
medium priority
Evidence
- vanityURLs/code
scripts/workers/worker.mjs— Worker accepts GET, HEAD, OPTIONS, POST /lookup/resolve, and POST /_analytics/lookup; other methods return 405. - vanityURLs/website
content/docs/reference/runtime-security.en.md— Runtime security docs list accepted public methods.
Related:
analytics-default, runtime-security-layers
Deployment
6How is a vanityURLs instance deployed?
The build generates
build/ and src/, then Cloudflare deploys src/worker.mjs with a Static Assets binding for build/. You can deploy manually with npx wrangler deploy --config wrangler.toml or let Cloudflare Workers & Pages run the build and deploy from Git.operator
contributor
high priority
Evidence
- vanityURLs/code
wrangler.toml— Worker uses src/worker.mjs with an ASSETS binding pointed at ./build and run_worker_first rules. - vanityURLs/code
package.json— deploy runs wrangler deploy; build runs scripts/build.mjs.
Should I run npm run update or npm run update -- --ref main?
For a normal production instance, run
npm run update. It refreshes product-owned files from the latest stable vanityURLs release tag. Use npm run update -- --ref main only when you intentionally want unreleased code, usually on a test instance or while validating a fix with maintainers. If you upgrade from main, commit that choice clearly and switch back to the normal command after the next release is published. See Upgrading an instance for the full workflow.operator
contributor
high priority
Evidence
- vanityURLs/code
scripts/upgrade.mjs— Default upgrades resolve the latest stable upstream release tag;--ref mainopts into a mutable branch. - vanityURLs/website
content/docs/reference/upgrading.en.md— The upgrading reference documents release-tag upgrades and the maintainer/testing use of--ref main.
Related:
worker-deployment, what-to-commit
Does vanityURLs use Cloudflare Pages?
The current runtime is a Cloudflare Worker using Static Assets, not a Cloudflare Pages
_redirects site. Some Cloudflare dashboards still mention Workers & Pages, but the deployed application is the Worker configured in wrangler.toml.operator
contributor
medium priority
Evidence
- vanityURLs/code
wrangler.toml— The runtime is a Cloudflare Worker with an [assets] binding, not a Pages _redirects deploy. - vanityURLs/code
package.json— The 3.0.0 release keeps the Cloudflare Worker as the current runtime.
Related:
worker-deployment, runtime-registry
Which files are generated and should not be edited directly?
Treat
build/ and generated src/ as build output. Edit source files in custom/, product files in defaults/ or scripts/ only when contributing upstream, then rebuild with npm run build or npm run check.operator
contributor
high priority
Evidence
- vanityURLs/code
scripts/build.mjs— Build cleans and regenerates build/ and copies Worker source from scripts/workers/ to src/. - vanityURLs/website
content/docs/reference/repository-layout.en.md— Repository layout docs classify build/ and src/ as generated output.
What should an instance repository commit?
Commit instance source files such as
custom/, wrangler.toml, and normal repository metadata. Do not commit regenerated build/, src/, or other transient output unless the project documentation changes to require it.operator
high priority
Evidence
- vanityURLs/code
scripts/clean.mjs— Clean removes generated output. - vanityURLs/website
content/docs/reference/repository-layout.en.md— Docs separate product-owned files, instance-owned files, and generated output.
What does npm run update or npm run upgrade replace?
The upgrade workflow refreshes product-owned files such as
defaults/, scripts/, package manifests, and LICENSE. It refuses protected local paths including custom/, wrangler.toml, .dev.vars, and README.md.operator
high priority
Evidence
- vanityURLs/code
scripts/upgrade.mjs— Default upgrade paths are defaults, scripts, package.json, package-lock.json, and LICENSE; protected paths include custom, wrangler.toml, .dev.vars, and README.md. - vanityURLs/code
package.json—updateis an alias fornpm run upgrade.
Command Line
4Where should I edit short links?
Edit
custom/v8s-links.txt, preferably through ./scripts/lnk for routine changes. defaults/v8s-links.txt is only the upstream starter fallback used when an instance has not created its own custom link file.operator
high priority
Evidence
- vanityURLs/code
scripts/lnk— CLI writes links to custom/v8s-links.txt unless V8S_LINKS_FILE overrides the path. - vanityURLs/code
scripts/build.mjs— Build prefers custom/v8s-links.txt and falls back to defaults/v8s-links.txt.
What does the lnk CLI manage?
./scripts/lnk manages local source files for links, schedules, random slug defaults, tags, and block policies. Successful write operations are designed to run checks and publish locally, so review its behavior before using it in a repository with custom Git-signing requirements.operator
contributor
high priority
Evidence
- vanityURLs/code
scripts/lnk— Usage covers links, schedules, tags, random slug settings, policy lists, blocked domains, blocked keywords, and allowed domains. - vanityURLs/website
content/docs/command-line-interface/lnk.en.md— The docs describe local link-management workflows.
Can one short link forward nested paths?
Yes. A splat link maps nested paths under a slug into a target containing
:splat; exact links win first, then the Worker chooses the longest matching splat prefix.operator
medium priority
Evidence
- vanityURLs/code
scripts/lnk—--splatcreates a splat link and stores SLUG/* in the links file. - vanityURLs/code
scripts/workers/worker.mjs— resolveLink checks exact links first, then longest splat prefix, and encodes :splat into the target.
Related:
link-source-of-truth, runtime-registry
What does npm run local-publish do?
npm run local-publish is a workstation convenience for validated instance changes: it runs checks, stages configured paths, chooses a commit message, commits, and pushes. Operators with required manual signing prompts should review this workflow before enabling it.operator
medium priority
Evidence
- vanityURLs/code
README.md— Local workflow says local-publish handles checks, commit selection, and push. - vanityURLs/code
docs/schema-changelog.md— v8s-local-config.json includes local_publish paths and commit messages.
Related:
lnk-cli, what-to-commit
Operator Configuration
3Why are there both defaults/ and custom/ directories?
defaults/ is the upstream product baseline; custom/ is the instance-owned overlay. Keeping local changes in custom/ lets npm run upgrade refresh product files without trampling instance links, branding, policies, or legal choices.operator
contributor
high priority
Evidence
- vanityURLs/code
docs/adr/0002-keep-instance-changes-in-custom.md— ADR establishes the split between upstream defaults and instance-owned changes. - vanityURLs/website
content/docs/reference/repository-layout.en.md— Docs explain product-owned defaults and instance-owned custom files.
Which operator fields must be real before launch?
Generated legal and trust pages require real
operator values for legal identity, short domain, jurisdiction, governing law, contact emails, last updated date, analytics disclosure, and abuse response window. Placeholder values are treated as configuration issues instead of launch-ready content.operator
trust-safety
high priority
Evidence
- vanityURLs/code
scripts/build.mjs— validateOperatorConfig requires legal_name, short_domain, jurisdiction, governing_law, contact, privacy, abuse, security, last_updated, analytics disclosure, and abuse window fields. - vanityURLs/code
docs/schema-changelog.md— Schema changelog lists expanded operator fields for privacy, terms, trust, security, and security.txt output.
Can I defer legal pages during setup?
Setup supports deferring full privacy, terms, and standalone security pages, but that is a setup convenience rather than legal clearance. Before public launch, operators should complete the generated pages or provide their own reviewed replacements.
operator
trust-safety
medium priority
Evidence
- vanityURLs/code
docs/adr/0005-support-deferred-legal-pages.md— ADR documents deferred legal-page mode through operator.legal_pages_enabled. - vanityURLs/code
package.json— The 3.0.0 release keeps deferred legal setup available during installation.
Privacy
3Are clicks logged by default?
The architecture has no built-in click database. Redirect, miss, pageview, and lookup events are sent only when an optional analytics provider is configured for the Worker.
operator
end-user
trust-safety
high priority
Evidence
- vanityURLs/code
scripts/workers/worker.mjs— Redirect events call logAnalyticsEvent with ctx.waitUntil, which is a no-op unless analytics provider variables are configured. - vanityURLs/website
content/docs/reference/analytics.en.md— Docs state analytics runs server-side and is configured with Worker variables.
How is visitor IP handled when Umami is enabled?
UMAMI_GEO_IP_MODE controls whether the Worker forwards full, truncated, or no visitor IP information to Umami. If Umami is configured and the mode is missing or invalid, the documented default is truncated.operator
end-user
trust-safety
high priority
Evidence
- vanityURLs/code
scripts/build.mjs— deriveUmamiGeoIpMode uses UMAMI_GEO_IP_MODE and defaults to truncated for Umami. - vanityURLs/website
content/docs/reference/analytics.en.md— Analytics reference documents full, truncated, and none modes for Umami IP handling.
Related:
analytics-providers, analytics-default
Why does the privacy model mention GDPR Article 11?
The default architecture does not create visitor accounts or a per-click identity database, so operators can explain that the redirector is not designed to identify visitors. That architectural fact does not remove obligations created by optional analytics, Cloudflare logs, local law, or operator-added tooling.
operator
trust-safety
medium priority
Evidence
- vanityURLs/website
content/docs/reference/analytics.en.md— Analytics docs distinguish architectural statelessness from optional provider collection. - vanityURLs/code
README.md— The product stores links and operator configuration in Git rather than visitor accounts.
Analytics
1Which analytics providers does vanityURLs support?
The documented provider choices are Umami and Fathom, configured through Worker variables and secrets. Both are server-side integrations from the Worker rather than browser JavaScript trackers.
operator
high priority
Evidence
- vanityURLs/website
content/docs/reference/analytics.en.md— Analytics reference documents Umami and Fathom variables and payloads. - vanityURLs/code
scripts/workers/worker.mjs— Runtime sends pageview, redirect, miss, lookup, and bot events through provider-specific analytics functions.
Related:
analytics-default, analytics-ip-handling
Scheduling
2How do scheduled links choose a destination?
Scheduled links evaluate rules in order using the configured timezone, weekdays, and
from/to window. The first active rule wins; if none match, the link uses its normal target.operator
end-user
high priority
Evidence
- vanityURLs/code
scripts/workers/worker.mjs— resolveScheduledTarget checks schedule rules in order and uses timezone-aware weekday/time windows. - vanityURLs/website
content/docs/reference/schedules.en.md— Schedule docs state that the first active rule wins and the normal link target is used otherwise.
Related:
schedule-timezones, link-source-of-truth
Which timezone does a scheduled link use?
A schedule rule uses its own
timezone when present; otherwise the Worker falls back to UTC. Use an IANA timezone such as America/Toronto to avoid guessing around daylight saving time.operator
medium priority
Evidence
- vanityURLs/code
scripts/workers/worker.mjs— Schedule rules use rule.timezone or UTC and Intl.DateTimeFormat for evaluation. - vanityURLs/code
docs/schema-changelog.md— Inline @schedule rules support timezone at schedule and rule level.
Related:
schedule-cli
Destination Policies
5What link lifecycle states exist?
A link can be
permanent, ephemeral, expired, disabled, maintenance, or deactivated. The Worker resolves the effective state before redirecting, so state pages or error routes can replace a normal redirect.operator
end-user
high priority
Evidence
- vanityURLs/code
scripts/lnk— VALID_STATES are permanent, ephemeral, expired, disabled, maintenance, and deactivated. - vanityURLs/code
scripts/validate-runtime-registry.mjs— The generated runtime registry must define routing for every required state.
What happens when a link has passed expires_at?
When
expires_at is a valid date in the past, the Worker treats the link as expired even if the stored state is different. The default expired route serves the expired state page instead of the destination.operator
end-user
high priority
Evidence
- vanityURLs/code
scripts/workers/worker.mjs— getEffectiveState returns expired when expires_at is a valid past date. - vanityURLs/code
scripts/validate-runtime-registry.mjs— expires_at must parse as a valid date when present.
Related:
lifecycle-states, state-page-statuses
Which HTTP statuses do state pages return?
The built-in state pages return meaningful status codes: disabled links return
403, expired links return 410, and maintenance links return 503. Deactivated links fall through to the not-found flow.operator
end-user
trust-safety
medium priority
Evidence
- vanityURLs/code
scripts/workers/worker.mjs— disabled returns 403, expired returns 410, and maintenance returns 503.
Related:
lifecycle-states, expires-at
How does vanityURLs prevent unsafe redirect destinations?
Build-time policy and runtime sanitation focus on HTTP(S) destinations without embedded credentials, private-network targets, localhost targets, or known risky destination patterns. Operators can replace the source policy in
custom/v8s-policies.json.operator
trust-safety
destination-owner
high priority
Evidence
- vanityURLs/code
defaults/v8s-policies.json— Default policy blocks private networks, localhost, auth-in-URL, unsafe protocols, and executable-style extensions. - vanityURLs/code
scripts/workers/worker.mjs— sanitizeRedirectTarget only allows http(s), requires a hostname, and rejects username/password in redirect targets.
Does custom/v8s-policies.json merge with the default policy?
No. When
custom/v8s-policies.json exists, it replaces the selected default policy source for the instance. This makes local policy ownership explicit and prevents removed local decisions from reappearing through an implicit merge. An empty or minimal custom policy is valid; copy defaults/v8s-policies.json into custom/ only when you want the defaults as an editable template.operator
contributor
medium priority
Evidence
- vanityURLs/code
scripts/build.mjs— copyRuntimeBlocklist chooses custom/v8s-policies.json when it exists; otherwise defaults/v8s-policies.json. - vanityURLs/code
docs/adr/0003-custom-policy-replaces-default-policy.md— ADR records replacement semantics for custom policy.
Related:
destination-policy, defaults-vs-custom
Localization
2How does the Worker choose a localized page?
For localizable HTML assets, the Worker checks
Accept-Language against the configured supported languages and serves the first available localized file. If no localized file is available, it falls back to the root asset, which is normally English.operator
end-user
medium priority
Evidence
- vanityURLs/code
scripts/workers/worker.mjs— fetchLocalizedAsset checks Accept-Language against generated LOCALIZED_HTML_LANGUAGES and falls back to the root asset. - vanityURLs/code
scripts/build.mjs— Build patches LOCALIZED_HTML_LANGUAGES from supported languages in v8s-site-config.json.
Related:
operator-placeholders, custom-public
How do I customize public pages and assets?
Put instance-owned public assets and page replacements under
custom/public/. During build, vanityURLs copies defaults/public/ first and then overlays custom/public/, so custom files win without editing upstream defaults. Product-owned runtime CSS and JavaScript use v8s- filenames and should normally stay in defaults/public/; copying them to custom/public/ creates a local shadow that can go stale after upgrades. Custom HTML receives a sandboxed compatibility profile that still allows same-host custom CSS, JavaScript, inline styles, inline scripts, forms, popups, downloads, and public lookup calls.operator
medium priority
Evidence
- vanityURLs/code
scripts/build.mjs— copyPublic overlays custom/public/ on top of defaults/public/ when custom public files exist and records them in build/v8s-custom-assets.json. - vanityURLs/website
content/docs/reference/custom-overrides.en.md— Custom overrides docs explain instance-owned file overlays.
Related:
defaults-vs-custom, localization-fallback
Trust And Safety
6How does security.txt work?
The Worker redirects
/security.txt to /.well-known/security.txt with a permanent redirect. The generated file depends on {{operator.short_domain}}, {{operator.security_contact}}, and {{operator.last_updated}}.operator
trust-safety
high priority
Evidence
- vanityURLs/code
scripts/workers/worker.mjs—/security.txtredirects to/.well-known/security.txt; the canonical path is served from assets. - vanityURLs/code
scripts/build.mjs— Generated security.txt uses operator.short_domain, operator.security_contact, and operator.last_updated.
Related:
operator-placeholders, abuse-reports
Which paths should Cloudflare Access protect?
The Worker treats localized stats paths such as
/en/_stats/ and /fr/_stats/, and localized tests paths such as /en/_tests/ and /fr/_tests/, as protected operational paths. Configure the Cloudflare Access application for */_stats, */_stats/*, */_tests, and */_tests/* path patterns. Legacy /_stats redirects to /en/_stats/, and legacy /_tests redirects to /en/_tests/. If CF_ACCESS_TEAM_DOMAIN or CF_ACCESS_AUD is missing, protected paths fail closed with 503 instead of becoming public.operator
high priority
Evidence
- vanityURLs/code
scripts/workers/worker.mjs— Localized stats and tests paths require Cloudflare Access JWT validation; legacy/_statsredirects to/en/_stats/and legacy/_testsredirects to/en/_tests/. - vanityURLs/website
content/docs/customize/access-control.en.md— Access control docs describe protecting operational surfaces.
Related:
cloudflare-access-jwt, runtime-security-layers
What does vanityURLs verify for Cloudflare Access?
For protected paths, the Worker checks the
cf-access-jwt-assertion token against the configured Cloudflare Access team domain and audience. It validates the token algorithm, issuer, audience, time window, and RS256 signature from the Access JWKS.operator
contributor
medium priority
Evidence
- vanityURLs/code
scripts/workers/worker.mjs— Access JWT verification checks RS256, issuer, audience, validity window, and JWKS signature.
Related:
protected-operational-paths
Why does vanityURLs use both Worker checks and Cloudflare security settings?
The Worker keeps application behavior deterministic, while Cloudflare edge controls should reject noisy traffic before it spends Worker CPU or analytics quota. Use both layers: Cloudflare for high-volume network protection, and Worker checks for application-specific redirect safety.
operator
contributor
trust-safety
high priority
Evidence
- vanityURLs/code
scripts/workers/worker.mjs— Worker blocks scanner probes, unsafe methods, private runtime files, and protected paths. - vanityURLs/website
content/blog/layering-cloudflare-protection-around-a-short-link-domain.en.md— Blog explains why WAF, bot controls, Access, and analytics layers answer different operational questions.
How are scanner probes handled?
Known scanner paths are matched against the incoming request before short-link lookup. Matching probes receive a plain no-store
404 and should not become normal short-link misses.operator
trust-safety
medium priority
Evidence
- vanityURLs/code
scripts/workers/worker.mjs— findScannerProbe loads v8s-blocklist.json and matches request-scoped scanner keywords before redirect lookup. - vanityURLs/code
defaults/v8s-policies.json— Default policy includes scanner-probe keywords for common PHP, WordPress, repository, and admin paths.
Related:
runtime-security-layers, destination-policy
How should someone report an abusive short link?
Send a report to {{operator.abuse_contact}} and include the short URL, destination if known, why it is harmful, and any supporting evidence. The default instance also publishes
/abuse-report.md as a structured template.end-user
destination-owner
trust-safety
high priority
Evidence
- vanityURLs/code
scripts/build.mjs— Generated Trust & Safety page directs reports to {{operator.abuse_contact}} and references /abuse-report.md. - vanityURLs/code
defaults/public/abuse-report.md— Default abuse report template is shipped as a public asset.
Terms And Liability
2Who is responsible for a deployed vanityURLs instance?
The instance operator configured in
custom/v8s-site-config.json is responsible for the domain, destinations, legal pages, abuse response, and operational choices for {{operator.short_domain}}. vanityURLs supplies code and defaults; it does not become the operator of each deployed instance.operator
end-user
trust-safety
high priority
Evidence
- vanityURLs/code
scripts/build.mjs— Generated terms identify {{operator.legal_name}} as the operator of {{operator.short_domain}}. - vanityURLs/code
defaults/v8s-site-config.json— operator fields include legal name, domain, jurisdiction, contact, privacy, abuse, and security contacts.
Does publishing a short link endorse the destination?
No. Generated terms state that short links may redirect to third-party websites and that publishing a short link does not endorse the destination or its operator. Abuse reports should target the short link and, when appropriate, the destination host or registrar too.
end-user
destination-owner
trust-safety
operator
medium priority
Evidence
- vanityURLs/code
scripts/build.mjs— Generated terms say third-party destinations are not controlled, monitored, or endorsed by the operator.
Related:
abuse-reports, who-operates-instance
Comparison
1When is vanityURLs a better fit than a hosted shortener?
vanityURLs is a strong fit when you want links as code, Git history, self-operated Cloudflare infrastructure, and no shared hosted-service account surface. Hosted shorteners usually win when you need a managed dashboard, team permissions, built-in billing support, or a public API without running your own deployment.
operator
contributor
medium priority
Evidence
- vanityURLs/code
README.md— Project emphasizes branded short-link domains as code on Cloudflare Workers. - https://dub.co/pricing — Hosted developer shortener pricing and feature tiers are organized around accounts and plans.
- https://bitly.com/pages/pricing — Mainstream hosted shortener pricing is plan-based.
Related:
hosted-service, stateless-architecture