The read-it-later solution you've been looking for.
PrivateΒ Β Β·Β Β
LightweightΒ Β Β·Β Β
Feature-packedΒ Β Β·Β Β
Delightfully-designed
Self-host in 5 minutes or try the hosted version β
Private by default. Your reading list shouldn't live on someone else's server. Someday runs entirely on hardware you control, with no tracking, no telemetry, and no third-party accounts to sign in to. Your library never leaves your server.
Lightweight and fast. One small app, one database file β that's the whole stack. It boots in seconds, idles on almost nothing, and stays snappy even with thousands of articles saved. Happy on a Raspberry Pi, a spare corner of your home server, or a $5 VPS.
Feature-packed where it counts. Most self-hosted read-later apps are beautiful but thin. Someday ships the things you'd actually pay for: email-to-save, Readwise import, highlights with notes, smart collections, similar-article discovery, 15-language translation, and full-text search β all running locally against your own data.
Beautifully designed. A distraction-free reader, keyboard-first navigation, thoughtful typography, hand-tuned light and dark themes, and a mobile layout that actually works. Designed for the "slow web."
Private, lightweight, and fast β by design. One process, one database file, one
docker compose up. No external services, no analytics, no heavy stack to maintain. Starts in seconds, happy on a Raspberry Pi. Jump to self-hosting β
|
Paste a URL, |
A distraction-free reader with typography you control, read-aloud, light and dark themes, and offline reading on the train. |
Tags, collections, and a triage mode that clears a two-hundred-item backlog in a couple of minutes. |
|
Select-to-highlight with inline notes and a side panel that follows you through the article. |
Boots in seconds, idles on almost nothing, runs on a Raspberry Pi. Fewer moving parts, fewer things to break. |
One database file. Take a copy and walk away whenever. AGPL-3.0 β you have the right to study and modify every line. |
- Paste-to-save from the topbar, or hit
βV/Ctrl+Vanywhere to save the URL on your clipboard. - Bookmarklet β drag the "Save to Someday" button from Settings to your bookmarks bar and save any page in one click, without leaving the tab.
- Email-to-save β forward any newsletter or article to your Someday address and it lands in your library seconds later, with the sender as byline. Setup guide below.
- Import from Pocket, Instapaper, Readwise Reader, Raindrop and Omnivore β one drop zone that auto-detects the format, ZIPs included. Tags, archive state, favourites, folders and saved dates are preserved. Runs in the background and survives a restart.
- Automatic handling for PDFs (saved as bookmarks), product pages (metadata-only), and tweets.
- Tracking parameters removed so shared links stay clean.
- No duplicates β re-saving a URL is a no-op.
- Readability-powered extraction strips ads, nav, pop-ups, and sidebars so you just read the article.
- Typography you control β size, line height, and measure width, plus a sans, a serif (Source Serif 4), a monospace, and Atkinson Hyperlegible, the Braille Institute's face for readers who find letterforms easy to confuse. Settings apply before the first paint, so nothing reflows, and they follow you to your other devices.
- Read aloud with the browser's own speech engine β no server, no cost, no account with anyone. The paragraph being spoken is highlighted as it goes, and lock-screen controls work on mobile.
- Light and dark themes, one-click toggle, remembers your choice.
- Paywall detection flags subscription-gated articles with a badge before you click through.
- Source badges tell you at a glance whether an article came in via email, is a product page, or a PDF.
- Save any article as a PDF via your browser's print dialog.
- Cover images, favicons, authors, and reading time β captured once, there whenever you open the article.
- Boots in seconds. No warm-up, no background sync jobs, no dashboards to load.
- Tiny footprint. One small container, one database file. Happy on a Raspberry Pi or the smallest VPS your provider sells.
- Instant everything. Search, filter, open an article β everything feels snappy, even with thousands of articles in your library.
- No moving parts. No external database, no Redis, no message queue. Fewer things to configure, fewer things to break, fewer things to update.
- Grows with your archive. Designed to stay fast as your library grows into the tens of thousands.
- Select-to-highlight in the reader β toggle highlight mode and drag across any passage.
- Your highlights stick. They survive translations, theme switches, and revisits.
- Four colours, so a highlight can mean something β quote it, argue with it, come back to it.
- Per-highlight notes β click any highlight to edit, annotate, or delete.
- Side panel lists every highlight in an article, with jump-to-text on click.
- A highlights library at
/highlightsβ everything you've ever marked, across every article, searchable and filterable by colour, with one-click copy as Markdown. - Share one as a public page at
/{username}/h/{id}β the passage, your note, and a link to the original. Per highlight, never per article, and off until you say so. GET /api/highlights.json?since=hands the lot to whatever you take notes in. Authenticate with an API token and poll; the cursor walks forward through your history.
Two organization primitives β use either, both, or neither.
| Tags | Collections | |
|---|---|---|
| Purpose | Flexible labels | Curated reading lists |
| Creation | Auto on first use | Explicit, you name them |
| Renaming | Merges on conflict | Simple rename |
| Filters | Respects read/unread | Shows everything in the list |
Plus built-in filters for Unread, Read, Favorites, and Archive, reading time (< 5 min β¦ > 20 min), and source domain.
- Searches every article β titles and full body text, including pieces you saved months ago.
- Partial matches work by default. Type
reactand findreactiveandreactortoo. - Ranked by relevance, not just date, and results arrive instantly as you type.
- Scoped to your library, respects whichever filter view you're in.
For every article you open, Someday surfaces up to five related pieces from your own library. Great for rediscovery β save an article today, and the next time you open it you'll see the related pieces you'd forgotten you'd saved.
- Translate any saved article into one of 15 languages with a click: English, Spanish, French, German, Portuguese, Italian, Dutch, Polish, Russian, Japanese, Chinese, Korean, Arabic, Turkish, Swedish.
- Formatting is preserved. Headings, lists, and quotes keep their structure β you get a clean translated article, not a wall of text.
- Fast even on long articles.
- No API keys required. Translation is powered by Lingva, a privacy-respecting proxy for Google Translate. By default it uses the public
lingva.mlinstance β setLINGVA_URLto your own instance if you prefer to keep article text entirely off third-party servers.
- Pick any future datetime (defaults to tomorrow 9 am). One reminder per article.
- They actually arrive. By email, or as a notification if you've allowed them on a device β and never for something you've already read or archived in the meantime.
- The bell icon shows a dot when any reminder is due within 24 hours.
- Upcoming reminders live in the sidebar, sorted by time, with click-to-cancel and a generous undo window.
Delivery runs on the same background queue as everything else β a reminder is just a job with a later start time, so there's no cron and no scheduler process. Email needs SMTP_HOST; push needs a VAPID key pair. Set neither and reminders still show up in the app, they just don't come find you.
A backlog exists because there's no cheap way to say no. Opening an article to decide about it costs the same as reading it, so nobody does, and the pile grows until looking at it feels bad.
Triage is one article at a time and four decisions: archive, file into a collection, keep, or read now. Arrow keys on a desktop, swipes on a phone, undo on everything. It hands you the oldest thing you haven't judged yet, and two hundred saved links take a couple of minutes to get through.
Filing is what stops triage from being a bin. Press β and then a number, and the article goes straight into one of your collections without leaving the queue β the decision you actually want for the thing you're keeping for a reason. Undo takes it back out, but only if triage was what put it there; an article you filed by hand last week stays where you put it.
Someday is built for readers who prefer their hands on the keyboard. Navigate the library, open articles, toggle read/favorite/archive, save from the clipboard, and dismiss menus β all without reaching for the mouse. Hit ? anywhere in the app to see every available shortcut.
Works beautifully on phones, tablets, and desktops. Someday ships as a Progressive Web App β add it to your home screen from any browser for a full-screen, app-like experience on iOS and Android, no app store required. Once installed, Someday appears in your device's share sheet β save anything from any app with one tap.
There is also a native iOS and Android client in mobile/ β Expo and React Native, sharing the reader and sync code with the web app. It reads, highlights, downloads for offline and accepts shares, against someday.sh or your own instance. It is not in the app stores yet, so for now it is something you build yourself; the PWA above is the route that needs nothing.
It works on the underground, too. Someday keeps your most recent unread articles and anything you've started reading on the device, so they open without a network β text, images, and your highlights. Save a link while offline and it goes into a queue that empties itself the moment you're back, even if you closed the tab in between.
Two things worth knowing about how this is built:
- No page you're signed into is ever cached. Article text is stored as plain data and rendered on the spot, so nothing keyed by URL alone contains your library.
- Signing out clears it. Someday runs on shared laptops, and a cache that outlives a session would hand the next person your reading.
Both light and dark themes are carefully designed for comfortable long-form reading. Toggle with one click; your preference is remembered across sessions.
| βοΈ Cloud (someday.sh) | π Self-host | |
|---|---|---|
| Setup | Sign up β zero config | Docker Compose, 5 minutes |
| Storage | Managed, encrypted | Your database file |
| Updates | Automatic | git pull && docker compose up -d --build |
| Backups | Automated, offsite | Your cron, your volume |
| Cost | Free up to 300 articles, then β¬4/month | Free (you pay for hosting) |
| Library size | 300 free, unlimited on Pro | Unlimited |
| Privacy | Hosted by us | Never leaves your server |
| Best for | "I just want to read." | "I want to own every byte." |
Both run the exact same open-source code β including the code that enforces the limit, which switches itself off when no payment provider is configured:
export async function getPlan(userId, region) {
if (!features().billing) return 'pro'; // no STRIPE_SECRET_KEY β everything unlocked
β¦
}That isn't a concession. A self-hosted instance with a crippled feature set would make the open-source release marketing rather than software.
On the hosted plan: hitting the limit refuses new saves with a message and nothing else. Nothing is deleted, nothing is hidden, and everything already saved stays readable, searchable and exportable. Imports are never capped on any plan β bring your entire Pocket library and decide afterwards.
Someday is available as a managed service at someday.sh.
What you get:
- Everything in this README, zero setup
- Managed updates and security patches
- Automated offsite backups
- Same AGPL-3.0 code, just hosted for you
Someday runs as a single process with a single database file. No database server, no Redis, no queue, no external dependencies beyond Node. That's what makes it lightweight enough to self-host comfortably on modest hardware.
Requirements: Docker 20+ with Compose v2.
git clone https://github.com/heindewilde/someday.git
cd someday
cp .env.example .envOpen .env and set ORIGIN to the public URL you'll serve from (required in production):
ORIGIN=https://someday.yourdomain.comStart it:
docker compose up -dThat's it. Someday is running on port 3000. Data lives in a Docker named volume (someday-data) and survives restarts and upgrades. A /health endpoint is wired up to the container's healthcheck so your orchestrator knows when it's ready. It also reports the running version β curl localhost:3000/health returns {"ok":true,"version":"0.5.0"} β so you can confirm an upgrade actually landed.
Change the port: set PORT=8080 in .env before starting. Remember to update ORIGIN to match.
Prebuilt multi-arch images (amd64 + arm64) are published to GitHub Container Registry on every push to main:
docker run -d --name someday -p 3000:3000 \
-v someday-data:/app/data \
-e ORIGIN=http://localhost:3000 \
ghcr.io/heindewilde/someday:latestPin to a specific release with :v1.2.3 instead of :latest. To build from source instead, clone the repo and run docker build -t someday ..
Requirements: Node.js 20+ (22 LTS recommended).
git clone https://github.com/heindewilde/someday.git
cd someday
npm ci
npm run build
PORT=3000 ORIGIN=http://localhost:3000 node buildPORT and ORIGIN must match β PORT is what the server listens on, ORIGIN is the URL your browser uses. Data is written to ./data/someday.db by default (override with DB_PATH).
To run as a service, wrap node build with systemd, pm2, or your supervisor of choice.
cd someday
git pull
docker compose up -d --buildNo manual migration step. Schema changes are applied automatically at startup. Your data is untouched during upgrades.
The entire app lives in data/someday.db. Back it up however you'd back up any SQLite file.
Live backup (no downtime):
sqlite3 /path/to/data/someday.db ".backup /path/to/backups/someday-$(date +%F).db"Daily cron:
0 3 * * * sqlite3 /srv/someday/data/someday.db ".backup /backups/someday-$(date +\%F).db"Offsite: pipe to restic, rclone, or rsync to your destination of choice. The database file is the whole app β no config, assets, or state lives outside of it.
Point your proxy at port 3000, forward Host and X-Forwarded-* headers, and set ORIGIN to your public URL.
If you're behind a proxy and want the auth rate limiter to see real client IPs (rather than the proxy's IP), also set ADDRESS_HEADER=x-forwarded-for and XFF_DEPTH=1 on the Someday container. Increase XFF_DEPTH if you have more than one proxy hop.
Caddy
someday.yourdomain.com {
reverse_proxy localhost:3000
}nginx
server {
listen 443 ssl http2;
server_name someday.yourdomain.com;
# SSL config (certbot, Let's Encrypt, etc.)
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Traefik (labels on docker-compose)
labels:
- "traefik.enable=true"
- "traefik.http.routers.someday.rule=Host(`someday.yourdomain.com`)"
- "traefik.http.routers.someday.entrypoints=websecure"
- "traefik.http.routers.someday.tls.certresolver=letsencrypt"
- "traefik.http.services.someday.loadbalancer.server.port=3000"All configuration is via environment variables (or a .env file).
| Variable | Default | Required? | Description |
|---|---|---|---|
ORIGIN |
http://localhost:3000 |
Yes in production | Public URL the app is served from. Must match the domain users hit. |
PORT |
3000 |
No | Port the Node server listens on. |
DB_PATH |
./data/someday.db |
No | Path to the SQLite database file (local file mode). |
DATABASE_URL |
β | No | Remote libSQL / Turso URL. Overrides DB_PATH when set. |
DATABASE_AUTH_TOKEN |
β | No | Auth token for remote libSQL. Required when DATABASE_URL points to a remote instance. |
DISABLE_REGISTRATION |
β | No | Set to true to block new signups. The first account can always be created so you can bootstrap your own instance with this already on. |
INBOUND_EMAIL_SECRET |
β | No | Shared secret for the Postmark inbound-email webhook. Required only if you're enabling email-to-save. |
LINGVA_URL |
https://lingva.ml |
No | Lingva translation instance to proxy to. The default public instance works out of the box. Override with your own Lingva instance if you want translation to stay entirely off third-party servers. |
JOB_CONCURRENCY |
4 |
No | How many background jobs run at once, per database. Parsing, imports and reminder delivery all share this pool. |
EXTENSION_ORIGINS |
β | No | Extra chrome-extension://β¦ origins allowed to call the API with a Bearer token. Only needed if you've loaded your own unpacked build. |
Email (optional). Leave SMTP_HOST unset and Someday stays a single process with no external services: the feedback button hides itself, reminders fall back to nothing, and password reset still works but prints the link to the container logs instead of mailing it.
| Variable | Default | Required? | Description |
|---|---|---|---|
SMTP_HOST |
β | No | Turns email on. Everything below is ignored without it. |
SMTP_PORT |
587 |
No | |
SMTP_USER / SMTP_PASS |
β | No | Credentials, if your relay wants them. |
SMTP_FROM |
β | No | The From address, e.g. Someday <noreply@yourdomain.com>. |
SMTP_SECURE |
auto | No | Force implicit TLS. Defaults to on for port 465, STARTTLS otherwise. |
FEEDBACK_EMAIL |
SMTP_FROM |
No | Where the in-app feedback button sends messages. |
Web Push (optional). With these set, readers can opt in per device and reminders arrive as notifications instead of email. Unset, the toggle doesn't appear. Generate a pair with npx web-push generate-vapid-keys.
| Variable | Default | Required? | Description |
|---|---|---|---|
VAPID_PUBLIC_KEY |
β | No | Turns push on, together with the private key. |
VAPID_PRIVATE_KEY |
β | No | Keep it secret; anyone holding it can push to your users. |
VAPID_SUBJECT |
SMTP_FROM, then ORIGIN |
No | Contact address for push services. Some reject pushes without one. |
Billing (optional, and not something a self-hoster should ever need). Unset, every account on the instance is unlimited, the pricing page returns 404, and no upgrade prompt exists anywhere in the UI. There is no way to accidentally run a paywalled instance.
| Variable | Default | Required? | Description |
|---|---|---|---|
STRIPE_SECRET_KEY |
β | No | Turns billing on. Without it getPlan() returns pro for everyone, before any query runs. |
STRIPE_PRICE_ID |
β | No | The recurring price to sell. |
STRIPE_WEBHOOK_SECRET |
β | No | Signing secret for the webhook endpoint. Without it every webhook is rejected β which is the right failure, since the signature is the only thing authenticating it. |
STRIPE_PRICE_LABEL |
β¬4/month |
No | Display only. Stripe holds the real amount. |
Multi-region (optional, and almost certainly not what you want when self-hosting). Set these to run one database per region; leave them unset and everything lives in one file.
| Variable | Default | Required? | Description |
|---|---|---|---|
DATABASE_URL_EU |
β | No | The primary. Holds the global email and username directories as well as EU data. |
DATABASE_URL_US |
β | No | |
DATABASE_URL_APAC |
β | No |
Forward any article, newsletter, or page to your Someday address and it lands in your library.
1. Create an inbound server in Postmark. In Postmark β Servers β create a new server β set stream type to Inbound.
2. Set the webhook URL. Set the inbound webhook to:
https://someday.yourdomain.com/api/inbound-email?secret=YOUR_SHARED_SECRET
Pick a long random YOUR_SHARED_SECRET (e.g. openssl rand -hex 32).
3. Set the secret in your Someday instance.
INBOUND_EMAIL_SECRET=YOUR_SHARED_SECRETRestart the container. Postmark will start POSTing inbound emails to Someday, which attributes each one to the registered user whose email matches the sender. Emails from unregistered addresses are silently dropped.
Forwarding tip: use your email client's forward-to rules or a service like Apple Mail Rules / Gmail filters to auto-forward newsletters to your Postmark inbound address.
Settings β Import β drop the file your old app gave you. Someday works out which service it came from and tells you what it found before importing anything. ZIPs are fine β no need to unpack them first.
Supported: Pocket (both the 2025 shutdown export and the classic ril_export.html), Instapaper, Raindrop, Omnivore, Readwise Reader, and Someday's own JSON export.
Imports run in the background with a live progress bar, survive a deploy or a closed tab, and preserve what the source recorded:
- Tags (auto-created as needed)
- Read / unread status
- Archive status
- Folders, as collections, where the source has them
- Original saved date
Existing URLs are skipped; no duplicates. Omnivore exports include the article text, so that one imports complete and instantly β nothing has to be re-fetched.
For the technically curious:
- Single-process SvelteKit app, server-rendered. No separate API, no microservices.
- One SQLite file for everything. Local by default; remote libSQL / Turso supported if you want it.
- Full-text search and similarity live inside SQLite β no separate search engine to run or maintain.
- Article parsing happens in the background, so saves are instant. Background work is a table in SQLite and an in-process worker β no Redis, no queue service, no second process to run.
run_atdoubles as the scheduler, so a reminder due next Tuesday is just a job with a start time, and there's no cron anywhere. - Migrations run automatically at startup, tracked in a
schema_migrationsledger. A failing migration fails the boot loudly rather than silently doing nothing. No manual steps on upgrade. - Session auth with bcrypt-hashed passwords and httpOnly cookies, plus API tokens (
sk_<region>_β¦) for the browser extension and scripts. Tokens can save and read; they deliberately cannot change your password, your email, or your billing. - Billing, where enabled, is hosted Checkout and a signed webhook β no card data reaches this server and there is no PCI scope. Subscription state lives in one global table because a Stripe webhook arrives with a customer id and no region; the plan is denormalised onto the user's own row so every quota check stays a local read.
- Offline reading is a service worker plus a JSON endpoint. Authenticated HTML is never cached β the article is fetched as data and rendered client-side, and everything private is dropped when you sign out.
- SvelteKit 2 + Svelte 5 (runes)
- Drizzle ORM + @libsql/client (SQLite)
- Mozilla Readability + jsdom β article extraction
- Tailwind CSS v4 + @tailwindcss/typography β prose styling
- lucide-svelte β icons
- bcryptjs β password hashing
- CUID2 β primary keys
- fflate β ZIP handling for imports and exports, in the browser and on the server
- nodemailer, web-push and stripe β all optional, all lazily loaded, none touched unless configured
- Lingva β translation proxy
- Web Speech API and Service Workers β read-aloud and offline reading, with no third party involved
Not promises β a rough direction. Open an issue to vote or propose changes.
- Digests β an optional weekly note about what's piled up.
- Full-text search across highlights, not just article bodies.
- An Obsidian plugin, or rather someone else's:
/api/highlights.jsonis there so it doesn't have to be ours. - Native apps in the stores β the iOS/Android client itself is built and lives in
mobile/; what's left is the App Store and Play releases, not the app.
PRs, issues, and discussions are all welcome. Someday is a small project and a friendly one β come as you are.
Quickstart:
git clone https://github.com/heindewilde/someday.git
cd someday
npm install
npm run dev # dev server on port 5173Before opening a PR:
npm run check # type-check with svelte-check
npm run test # vitestBoth run in CI. The tests use a real in-memory database put through the real migration runner rather than mocks, so a suite that passes is evidence the schema works. Keep changes focused, match the existing style, and update the Architecture section of this README if you change how the system is structured.
Conventions:
- Svelte 5 runes (
$state,$derived,$effect,$props) β no legacy Options API. - Scoped
<style>blocks with CSS custom properties β no Tailwind utility classes in component markup. lucide-svelte@0.577.0for icons (specific version β 1.0.1 breaks Svelte 5 stable).
Where to start:
- Browse good-first-issue labels.
- Join Discussions for design questions.
- Anything on the roadmap is fair game β say hi on the relevant issue before starting large work.
Why another read-later app? Because the good ones are either expensive SaaS (Readwise Reader, Matter), increasingly stagnant (Pocket, Instapaper), or beautifully bare-bones (most self-hosted options). Someday aims for the middle: feature depth without the data surrender, in a package light enough to run on a Pi β free and unlimited if you host it, and a fraction of the price of the alternatives if you'd rather we did.
How does it compare to Pocket / Instapaper / Readwise Reader? Roughly feature-par with Pocket and Instapaper on saving, reading, tagging, and archiving. Closer to Readwise Reader on highlights, smart organization, and discovery β but without the cloud-only lock-in or the monthly bill.
Can I run this on a Raspberry Pi?
Yes. A Pi 4 with 2 GB RAM handles a single-user library of thousands of articles comfortably. The Docker image runs on both arm64 and amd64.
Is my reading list truly private?
Yes, with one nuance. Someday only reaches out to the internet for three things: (1) fetching the article URL you save, (2) fetching the favicon and cover image that article references, and (3) if you click Translate, proxying the article text through Lingva β a privacy-respecting Google Translate proxy that strips tracking identifiers. By default this goes through the public lingva.ml instance. If you want translation to stay entirely on-premises, run your own Lingva instance and point LINGVA_URL at it. No telemetry, no analytics, no third-party SDKs.
Can I import my existing library?
Yes β Pocket (both the 2025 shutdown ZIP and the older ril_export.html), Instapaper, Readwise Reader, Raindrop, Omnivore, and Someday's own JSON backup. Drop the file exactly as the service gave it to you; Someday works out which it is. Omnivore imports best of all, because its export contains the full article text, so nothing has to be re-fetched.
Does it work offline? Yes, properly. Your most recent unread articles and anything you've started reading are kept on the device automatically, with their images and your highlights, and open with no network. Saving a link while offline queues it and sends it when you're back. Translation and similar-article search still need a connection.
Is it free? Self-hosting is free and unlimited, always β the quota code disables itself when no payment provider is configured, so there is no crippled build. On the hosted someday.sh, the first 300 articles are free and Pro is β¬4/month for an unlimited library. Hitting the free limit only refuses new saves: nothing is deleted, everything stays readable and exportable, and imports are never capped on any plan.
What happens to my data if I stop self-hosting? You have the database file. It's a plain SQLite database β you can open it in DB Browser for SQLite, query it with any SQLite client, or import it into a different tool. No lock-in by design.
- Mozilla Readability β the article-extraction engine that makes reading-mode apps possible.
- Lingva and its public instance maintainers β free, private translation without a Google API key.
- SvelteKit and Drizzle teams for building tools that make small projects feel powerful.
- lucide for icons that look good at any size.
- Braille Institute of America for Atkinson Hyperlegible, and Adobe for Source Serif 4 β both under the SIL Open Font License, both bundled in
static/fonts/with their licenses. - Everyone who self-hosts, files issues, and keeps the open web open.
AGPL-3.0. See LICENSE for the full text.
In plain English:
- You can run Someday on your own server, for yourself or your family or your company, forever, for free.
- You can modify the source code however you like.
- If you offer modified Someday as a network service to others (i.e. you build a paid hosted version), you must publish your modifications under AGPL-3.0 too.
This is deliberate β Someday is and will remain open. If AGPL concerns you and you'd like different terms, open a discussion.