{"id":51217808,"url":"https://github.com/visorcraft/roamarr","last_synced_at":"2026-06-29T06:00:56.456Z","repository":{"id":367768550,"uuid":"1278401249","full_name":"visorcraft/Roamarr","owner":"visorcraft","description":"The private, self-hosted travel organizer for every moving part of a trip. Track flights, stays, documents, companions, reminders, expenses, and sharing in one SQLite-backed itinerary hub - all powered by SvelteKit, SQLite, and Drizzle.","archived":false,"fork":false,"pushed_at":"2026-06-28T05:07:24.000Z","size":11609,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-06-28T05:22:08.029Z","etag":null,"topics":["docker","drizzle","itinerary","nodejs","podman","privacy","self-hosted","sqlite","svelte","sveltekit","travel","travel-app","travel-management","travel-organizer","travel-planner","trip-management","trip-planner","typescript"],"latest_commit_sha":null,"homepage":"https://www.Roamarr.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/visorcraft.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"docs/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-23T18:54:12.000Z","updated_at":"2026-06-28T05:07:28.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/visorcraft/Roamarr","commit_stats":null,"previous_names":["visorcraft/roamarr"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/visorcraft/Roamarr","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visorcraft%2FRoamarr","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visorcraft%2FRoamarr/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visorcraft%2FRoamarr/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visorcraft%2FRoamarr/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/visorcraft","download_url":"https://codeload.github.com/visorcraft/Roamarr/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/visorcraft%2FRoamarr/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34915002,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-29T02:00:05.398Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","drizzle","itinerary","nodejs","podman","privacy","self-hosted","sqlite","svelte","sveltekit","travel","travel-app","travel-management","travel-organizer","travel-planner","trip-management","trip-planner","typescript"],"created_at":"2026-06-28T05:03:29.997Z","updated_at":"2026-06-29T06:00:56.449Z","avatar_url":"https://github.com/visorcraft.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- SPDX-FileCopyrightText: 2026 VisorCraft LLC --\u003e\n\u003c!-- SPDX-License-Identifier: GPL-3.0-only --\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"static/icon-512.png\" alt=\"Roamarr logo\" width=\"250\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eRoamarr\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eA private, self-hosted travel organizer for every moving part of a trip.\u003c/b\u003e\n  \u003cbr /\u003e\n  Keep flights, stays, documents, companions, reminders, expenses, and sharing in one itinerary hub.\n  \u003cbr /\u003e\n  SvelteKit app shell · single-container deploy · encrypted sensitive fields · no hosted travel account required.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/visorcraft/Roamarr/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/visorcraft/Roamarr?sort=semver\" alt=\"Latest release\" /\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-GPL--3.0--only-blue.svg\" alt=\"License: GPL-3.0-only\" /\u003e\u003c/a\u003e\n  \u003cimg src=\"https://img.shields.io/badge/SvelteKit-2-ff3e00?logo=svelte\u0026amp;logoColor=white\" alt=\"Built with SvelteKit 2\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/SQLite-Drizzle-003b57?logo=sqlite\u0026amp;logoColor=white\" alt=\"SQLite with Drizzle ORM\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/Node.js-%3E%3D22.12-339933?logo=node.js\u0026amp;logoColor=white\" alt=\"Node.js 22.12 or newer\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/container-Docker%20%2F%20Podman-892ca0?logo=podman\u0026amp;logoColor=white\" alt=\"Docker or Podman container\" /\u003e\n\u003c/p\u003e\n\n---\n\n## Screenshots\n\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd width=\"50%\"\u003e\n      \u003cimg src=\"docs/screenshots/dashboard.png\" alt=\"Roamarr dashboard with upcoming trips, reminders, and travel planning metrics\" /\u003e\n      \u003cbr /\u003e\n      \u003csub\u003e\u003cb\u003eDashboard\u003c/b\u003e — trips, reminders, documents, and recent activity.\u003c/sub\u003e\n    \u003c/td\u003e\n    \u003ctd width=\"50%\"\u003e\n      \u003cimg src=\"docs/screenshots/trip-itinerary-people.png\" alt=\"Roamarr trip people tab with companions, attendees, and sharing controls\" /\u003e\n      \u003cbr /\u003e\n      \u003csub\u003e\u003cb\u003eTrip people\u003c/b\u003e — companions, attendees, and itinerary sharing.\u003c/sub\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd width=\"50%\"\u003e\n      \u003cimg src=\"docs/screenshots/trip-itinerary.png\" alt=\"Roamarr trip itinerary tab with map hero, timeline cards, and trip stats\" /\u003e\n      \u003cbr /\u003e\n      \u003csub\u003e\u003cb\u003eTrip itinerary\u003c/b\u003e — map hero, timeline cards, tabs, and stats.\u003c/sub\u003e\n    \u003c/td\u003e\n    \u003ctd width=\"50%\"\u003e\n      \u003cimg src=\"docs/screenshots/trip-itinerary-globe.png\" alt=\"Roamarr trip 3D globe modal with city dots, country borders, and the destination centered\" /\u003e\n      \u003cbr /\u003e\n      \u003csub\u003e\u003cb\u003eTrip globe\u003c/b\u003e — interactive 3D Earth with cities, borders, and click-to-coordinates.\u003c/sub\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n  \u003ctr\u003e\n    \u003ctd width=\"50%\"\u003e\n      \u003cimg src=\"docs/screenshots/loyalty.png\" alt=\"Roamarr loyalty programs page with airline and hotel membership balances\" /\u003e\n      \u003cbr /\u003e\n      \u003csub\u003e\u003cb\u003eLoyalty programs\u003c/b\u003e — memberships, balances, notes, and travel rewards.\u003c/sub\u003e\n    \u003c/td\u003e\n    \u003ctd width=\"50%\"\u003e\n      \u003cimg src=\"docs/screenshots/insurance.png\" alt=\"Roamarr insurance policies page with coverage dates, policy numbers, and add-policy controls\" /\u003e\n      \u003cbr /\u003e\n      \u003csub\u003e\u003cb\u003eInsurance policies\u003c/b\u003e — coverage details, policy dates, and trip protection.\u003c/sub\u003e\n    \u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n---\n\n## What is Roamarr?\n\nRoamarr is a TripIt-style travel organizer you run yourself. It is built as a\nsingle Node.js application with a SQLite database, server-rendered SvelteKit\npages, and a practical app shell designed for repeated use rather than a\nmarketing dashboard.\n\nRoamarr can:\n\n- Track trips, itinerary segments, dates, timezones, booking status, notes,\n  tags, favorites, archives, comments, printable itineraries, and trip-page maps\n  of the next upcoming city.\n- Manage flights, hotels, trains, rental cars, rideshares, shuttles, boats,\n  food plans, events, parking, directions, points of interest, todos, and free\n  form notes.\n- Share trips with users, groups, public links, and calendar feeds with\n  read/edit/detail controls and token expiry.\n- Keep traveler context close to the itinerary: companions, documents, loyalty\n  programs, payment cards, insurance policies, entry requirements, medications,\n  emergency contacts, important items, and home-preparation tasks.\n- Coordinate family and group travel with attendee lists, polls, packing\n  templates, kid gear, accessibility notes, dietary details, room preferences,\n  and emergency itinerary sharing.\n- Track trip expenses with multiple currencies, exchange rates, receipt\n  attachments, splits, settlements, budgets, and payment due dates.\n- Import and export trip data as JSON or CSV, including dry-run previews before\n  importing.\n- Send reminders and operational notifications in app, by SMTP, or through\n  signed webhooks.\n- Run admin workflows for setup, users, registration, audit logs, scheduled\n  jobs, backups, restores, demo data, instance stats, health checks, and map\n  configuration (GeoNames city import and raster tile providers).\n- Surface license text, runtime credits, package attribution, and app version\n  details from the Settings -\u003e About area.\n\n## Your itinerary, under your roof\n\nTravel plans have a strange shape. The critical data is scattered across airline\nconfirmations, hotel portals, calendar invites, PDF receipts, family texts,\nmedicine lists, passport dates, and last-minute reminders. Roamarr is meant to\npull that data into one place without handing it to another hosted itinerary\nprovider.\n\n### One local database\n\nRoamarr stores application data in SQLite through Drizzle ORM and\n`better-sqlite3`. By default the database lives at `./roamarr.db`, and receipt\nattachments are stored beside it in an `attachments/` directory. Move the\ndatabase path, back it up, snapshot it, or keep it on persistent storage that\nfits your own setup.\n\n### Private by default\n\nThe app requires a `ROAMARR_SECRET` before boot. Sensitive fields such as travel\ndocument numbers, fare-provider API keys, and the SMTP password are encrypted at\nrest with AES-256-GCM. Passwords use argon2id, session cookies contain random\ntokens, and the database stores only token hashes.\n\nPublic share links and calendar feeds use reduced viewer data instead of\ndumping every private field attached to a trip. Roamarr is built around the\nidea that itinerary sharing should be explicit, scoped, and revocable.\n\n### Built for the actual trip\n\nRoamarr is not just a date list. It tracks the practical, unglamorous work that\nhappens before and during travel: who is coming, who needs what, what is paid,\nwhat is missing, what expires soon, what needs to be packed, who can see the\nitinerary, and what should happen if plans change.\n\n## Setup\n\n### Requirements\n\n- Node.js 22.12 or newer.\n- npm, using the checked-in `package-lock.json`.\n- SQLite support through the bundled `better-sqlite3` dependency.\n- A persistent database path for local app data.\n- `ROAMARR_SECRET`, generated with `openssl rand -base64 32`.\n\nIf native npm packages need to build on your machine, install your platform's\nstandard C/C++ build tools before running `npm ci`.\n\n### From source\n\n```bash\ngit clone https://github.com/visorcraft/Roamarr.git\ncd Roamarr\n\nnpm ci\ncp .env.example .env\nopenssl rand -base64 32\n```\n\nPaste the generated secret into `.env`:\n\n```env\nROAMARR_SECRET=replace-with-output-from-openssl\nDATABASE_PATH=./roamarr.db\nPORT=3000\nORIGIN=http://localhost:5173\n```\n\nThen start the development server:\n\n```bash\nnpm run dev\n```\n\nOpen `http://localhost:5173/setup` on first boot.\n\n### Production build\n\n```bash\nnpm ci\nnpm run build\nnpm start\n```\n\nThe production server listens on `PORT` or `3000` by default. Set `ORIGIN` to\nthe public URL when Roamarr is behind a reverse proxy so cookies and redirects\nare generated correctly.\n\nDeployment packaging should live outside this source repository. This repository\nis focused on building, testing, and running the Roamarr application from\nsource.\n\n## Configure Roamarr\n\n### Environment\n\n| Variable | Required | Default | Notes |\n| -------- | -------- | ------- | ----- |\n| `ROAMARR_SECRET` | yes | none | Base64 32-byte key used for encryption. The app refuses to boot if unset. |\n| `DATABASE_PATH` | no | `./roamarr.db` | SQLite file path. Attachments are stored in an `attachments/` directory beside this database. |\n| `PORT` | no | `3000` | adapter-node listen port. |\n| `ORIGIN` | no | none | Public origin for cookies and redirects, especially behind reverse proxies. |\n\nSMTP, webhooks, registration policy, themes, fare providers, backups, and most\nadmin settings are configured inside the app after setup.\n\n### Runtime data\n\n| Data | Default path |\n| ---- | ------------ |\n| SQLite database | `./roamarr.db` |\n| Receipt attachments | `./attachments/` |\n| Production build output | `./build/` |\n| SvelteKit build cache | `./.svelte-kit/` |\n\nLocal `.env` files, databases, logs, build output, dependencies, Playwright\nartifacts, and local QA screenshots are ignored by Git. Commit only templates\nsuch as `.env.example`.\n\n## Tweak Roamarr\n\n### Common workflows\n\n```bash\n# Start the dev server\nnpm run dev\n\n# Type-check Svelte and TypeScript\nnpm run check\n\n# Run the Vitest suite once\nnpm test\n\n# Build the production app\nnpm run build\n\n# Run the built app\nnpm start\n\n# Regenerate bundled license and credits data\nnpm run credits:generate\n\n# Generate a new Drizzle migration after schema changes\nnpm run db:generate\n```\n\nMigrations are applied automatically during application boot before the\nscheduler starts.\n\n### Application settings\n\nAfter the first setup flow, use Settings for:\n\n- Instance name, public registration, and admin controls.\n- SMTP delivery, signed webhooks, and per-user notification channels.\n- Fare provider accounts and connection tests.\n- Backups, restores, scheduled jobs, audit logs, health information, and demo\n  data.\n- About, project license, third-party package credits, and runtime component\n  acknowledgements.\n\nUse Profile for:\n\n- Password changes, email changes, and active session management.\n- Calendar feed token management.\n- Per-user theme selection, including High Contrast.\n\n## Architecture\n\nRoamarr is a SvelteKit 2 app using Svelte 5, TypeScript ES modules,\n`@sveltejs/adapter-node`, Tailwind CSS v4, Drizzle ORM, SQLite, Luxon,\nNodemailer, MapLibre GL JS, and Vitest.\n\nStartup imports `src/hooks.server.ts`, requires `ROAMARR_SECRET`, applies\nmigrations, ensures default settings and benefit templates exist, then starts a\nguarded in-process scheduler. The scheduler runs reminders, fare checks,\nexpired-session cleanup, and run pruning without duplicate starts or\noverlapping ticks.\n\nRoutes stay thin. Server-side business logic lives under `src/lib/server/`.\nAuthorization is centralized in sharing and ownership helpers, while public\nshare and calendar-feed routes expose only a reduced viewer projection.\n\nThe main app shell lives in `src/routes/+layout.svelte` and\n`src/routes/+layout.server.ts`. Shared components, icons, themes, labels, and\nformatting helpers live under `src/lib/`. Database schema and migrations live\nunder `src/lib/server/db/` and `drizzle/`. Map rendering uses MapLibre GL JS\nwith configurable raster tile providers; city data is imported from GeoNames\n`cities1000.zip`.\n\n## Contribute\n\nContributions are welcome through the standard fork-and-pull-request workflow.\nStart with [CONTRIBUTING.md](CONTRIBUTING.md), which covers local setup,\ncoding standards, tests, documentation expectations, dependency policy, and\npull request requirements.\n\nThe short version:\n\n```bash\ngit clone https://github.com/\u003cyou\u003e/Roamarr.git\ncd Roamarr\ngit checkout -b fix-or-feature-name\n\nnpm ci\nnpm run check\nnpm test\nnpm run build\n```\n\nBefore opening a pull request, include focused tests for behavior changes,\nupdate relevant docs, and regenerate license data after dependency changes.\n\n## Documentation\n\n- [CONTRIBUTING.md](CONTRIBUTING.md) - contribution guidelines\n- [docs/SECURITY.md](docs/SECURITY.md) - security policy and disclosure process\n- [LICENSE](LICENSE) - GPL-3.0-only license text\n- [static/manifest.json](static/manifest.json) - PWA manifest\n- [drizzle/](drizzle/) - generated database migration baseline\n\n## License\n\nRoamarr is licensed under GPL-3.0-only. See [LICENSE](LICENSE) for the full\nlicense text, [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines,\nand [docs/SECURITY.md](docs/SECURITY.md) for the security disclosure policy.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvisorcraft%2Froamarr","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvisorcraft%2Froamarr","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvisorcraft%2Froamarr/lists"}