pongolinks is a single-user self-hosted bookmark library for saving, organizing, and rediscovering links.
- Save bookmarks with title, description, and Tags.
- Filter bookmarks by included Tags, excluded Tags, Bookmark URL host, and search text.
- Extract Related Links from bookmark descriptions.
- Save the current page through a Bookmarklet or the Chrome browser extension.
- Check whether the current browser tab URL is already saved through the Chrome extension.
- Bun
- Monorepo: Bun workspaces and Turborepo
- Backend: Bun, Elysia, Elysia Eden contract, Basic Auth
- Frontend: Vue SPA, Vue Router, Vite, Tailwind CSS
- Database: SQLite through Drizzle ORM and
@libsql/client - Testing: Vitest
- Formatting: oxfmt
The project uses vertical slices. Feature behavior lives near the feature that owns it, while durable database schema and stable shared contracts live in workspace packages.
Read these documents before changing architecture or domain language:
docs/architecture.mdCONTEXT.mdfor ubiquitous language
Operational errors use the shared Rust-style Result<T, E> pattern. Exceptions are reserved for programmer errors, failed invariants, and test assertions.
├── apps/
│ ├── backend/ Bun/Elysia server, API, Eden contract, production entrypoint
│ ├── frontend/ Vue SPA and browser UI
│ └── extension-chrome/ Chrome extension source and build output
├── packages/
│ ├── db/ Drizzle schema, relations, client, and migrations
│ └── shared/ Stable cross-workspace TypeScript contracts and helpers
├── docs/
│ ├── adr/ Architecture Decision Records
│ └── architecture.md Project-wide architecture rules
├── CONTEXT.md Domain glossary and relationships
├── package.json Root workspace scripts
└── turbo.json Turborepo pipeline
Install Bun, then install dependencies from the repository root:
bun installCreate local environment values. The backend requires Basic Auth credentials:
BASIC_AUTH_CREDENTIALS=admin:admin
DATABASE_PATH=.data/pongolinks.sqliteDATABASE_PATH is optional if you want the default local SQLite path.
Run database migrations:
bun run db:migrateStart the backend and frontend development servers:
bun run devThe frontend dev server uses the /pl/ base path and proxies /pl/api to the backend on port 3000.
OpenAPI: http://localhost:3000/openapi
The Chrome extension source is in apps/extension-chrome. In source form it targets the local app at:
http://localhost:3000/pl/
Build a loadable extension from the repository root:
bun run extension:build https://example.com/pl/The URL must be an HTTP(S) app base URL ending with /. The command writes apps/extension-chrome/dist, which can be loaded as an unpacked Chrome extension.
