visitor@nextdash: ~ — nextDash – Your bookmarks. Your terminal. Your rules. 19 posts

nextDash

Latest version on GitHub is v1.13.1

Your bookmarks. Your terminal. Your rules.

visitor@nextdash:~$ ls -la ./posts

latest

From the devlog

nextdash-1-11-x-we-moved-your-furniture-and-left-a-note.md 17K

nextDash 1.11.x: we moved your furniture, and left a note

The largest release so far, and most of it answers one question: where does a thing live. The header is one row, the buttons that floated over the grid have somewhere to stand, config opens on tiles, the bookmark list is a workbench, and a fresh install starts on a new look – with a one-minute tour for everyone who already knew where things were.

ls posts/ -la

field guide

Take your bookmarks back

nextDash is a keyboard-first, self-hosted bookmark dashboard. No accounts, no cloud, no noise. It runs as a single binary or one Docker container, keeps everything in a folder you own, and tells you which of your links are already dead. This guide covers v1.4.0 - widgets, sources that bring links in on their own, saved page copies, and outgoing webhooks.

$ git clone skip to install ↓

0accounts to create
0Go dependencies
0keyboard shortcuts
0built-in themes
0UI languages
0uptime history
01

Why bookmarks rot

Everyone's bookmarks end up the same way: a bar full of favicons with no labels, folders you never open, and a long tail of links that quietly stopped working years ago.

The problem is not storage. Every browser stores bookmarks perfectly well. The problem is that a bookmark collection is write-only: you add to it constantly, you search it almost never, and nothing in the system ever tells you a link has gone. A site that now redirects to a parked page full of ads looks, to your bookmark bar, exactly like the site you saved.

Hosted tools solve the organising part, but they ask for an account and a copy of your links on somebody else's server. That trade never sat right for something as personal, and as boring, as a list of URLs.

My bookmark bar had become a graveyard, so I built a self-hosted dashboard that tells me which links are already dead.

nextDash starts from that diagnosis: a dashboard you actually open, driven entirely from the keyboard so that using it costs nothing, with a health view that treats link rot as a subject in its own right rather than an afterthought.

02

What nextDash is, in one minute

Seven things it does that a bookmark bar does not. Everything else in this guide is detail hanging off these.

01 · Organise

Pages, categories

Unlimited pages holding categories that hold bookmarks. Jump with 1-9.

02 · Navigate

Every keystroke

j/k move, Enter opens, a shortcut opens a site the moment you finish typing it.

03 · Find

Six ways to search

> / @ : ? * - plus your browser's own address bar, since v1.4.0.

04 · Capture

Inbox & sources

Paste, extension, share sheet - or a Source that polls GitHub, Raindrop, HN, YouTube or Mastodon for you.

05 · Maintain

Health & uptime

Per-bookmark checking, 30 days of history, drift detection, downtime alerts with action buttons.

06 · See

Widgets

A block on a page can hold a health board, an uptime chart or your inbox count instead of links.

07 · Own

Plain files

JSON in a folder you chose. One ZIP holds everything, your whole data dir since v1.4.0.

The nextDash dashboard: several columns of categories, each holding bookmark rows with favicons, shortcut chips and response times.
$ the dashboard: categories in columns, bookmarks as rows - shown in the default theme, 213 more to switch to
03

Is this for you?

Worth being honest about before you spend an evening on it. nextDash is opinionated, and the opinions rule some people out.

You will probably love it if...

  • You already self-host something - a NAS, a VPS, a Raspberry Pi, a Docker host.
  • You reach for the keyboard first and resent tools that make you point at things.
  • Your bookmarks number in the hundreds or thousands and you have lost track of them.
  • You want a start page that is also a dashboard for your own services - now with widgets for that.
  • You care that your reading list is not somebody else's dataset.
  • You have been burned by a service shutting down and taking your saved links with it.

You should look elsewhere if...

  • You need user accounts and permissions. There are none, by design.
  • You want to expose it publicly. The README is blunt: do not expose nextDash directly to the public internet.
  • You want a read-later app that stores article text. Local copies (v1.4.0) are a safety net, not a reading queue.
  • You want a feed reader. Fresh counts new entries; it does not show them.
  • You want a hosted service with an app store listing and a support desk.
04

Running in two minutes

One container, one folder, one port. No database to provision, no migration to run, no account to create.

services:
  nextDash:
    image: ghcr.io/jordibrouwer/nextdash:latest
    container_name: nextDash
    ports:
      - "8080:8080"
    volumes:
      - ./data:/app/data
    environment:
      - PORT=8080
      # Optional on LAN/VPS - require X-NextDash-Token on destructive API calls:
      # - NEXTDASH_WRITE_TOKEN=change-me-to-a-long-random-string
    restart: unless-stopped
  1. Bring it up and open it

    docker compose up -d, then http://localhost:8080. No setup wizard, no login. A quick-start card greets a brand-new install; the tour is always available again from Config -> Help.

  2. Bring in what you already have

    Export bookmarks from Chrome, Firefox or Edge as HTML - or, new in v1.4.0, from Pocket, Pinboard, Raindrop, linkding, Shiori, Linkwarden or Karakeep, since they all export the same format. Folders become categories; tags, notes and the saved date all survive the trip.

  3. Learn three keys

    > to search, : for commands, ! for the cheat sheet. Everything else can wait.

Prefer no Docker?

A single Go binary with two dependencies - gorilla/mux for routing, golang.org/x/net for the rest. go build -o nextDash && ./nextDash is the whole build (Go 1.24). Data goes to ./data unless NEXTDASH_DATA_DIR says otherwise.

Before you go beyond localhost

There are no user accounts. Anyone who can reach the URL can read and change everything. Set NEXTDASH_WRITE_TOKEN and put it behind Tailscale or an authenticating proxy. Section 16 covers this properly.

05

The mental model

Three levels of structure, five views. Once these click, the rest of the app is discoverable.

page          a tab across the top - "main", "work", "media". Keys 1-9.
 └─ category  a column heading - "vps", "tools", "reading". Collapsible, sortable.
     └─ bookmark   a row - name, URL, favicon, shortcut, tags, note, health status.
 └─ widget    since v1.4.0 - a block among the categories, one or two columns wide.

A bookmark belongs to exactly one category on exactly one page. Everything else - tags, smart collections, search filters, the inbox - is a view over that structure rather than a second hierarchy. Widgets share the same ordering list as categories, so there is one answer to where anything sits on a page, not two lists that can disagree.

ViewHow to get thereWhat it is for
DashboardEscThe grid of categories, bookmarks and widgets. Your start page.
InboxShift+I · 0The holding area for links you saved before deciding where they belong.
HealthShift+HEverything that needs attention across all pages.
Search>Since v1.4.0 has its own address (#search?q=...), so it can be bookmarked or shared like any other view.
ConfigShift+S · <Nine sections, each deep-linkable - including Sources and Widgets.

A detail that tells you a lot about the project

Reopen config within five minutes and it returns to the exact section and sub-tab you left. After that it starts on Overview, because by then you have probably come back for something else.

The dashboard top bar: page numbers, a widgets icon, an inbox count, a health pulse and the config gear - the five views from the table above, one keystroke or click away.
$ the five views, top right: pages, widgets, inbox, health, config
06

Everything is a keystroke

164 shortcuts across a dozen groups - but you need about ten of them to be faster than you were before.

There is one rule holding the whole scheme together: every action on a bookmark is Shift plus a letter. Shift+E edits, Shift+V previews, Shift+L shares, Shift+S always opens config. Bare letters act on the first press. k and j move the highlight.

The first ten

KeyWhat it does
j k ← →Move the highlight around the grid.
EnterOpen the highlighted bookmark. Ctrl/Cmd+Enter opens it in a new tab.
1-9Switch page. Shift+Left/Right cycles, comma shows an overview with counts.
>Search. Start typing; Enter opens the top result.
:Command palette - five collapsible groups, recent commands at the top.
&Quick add. Type name | url | shortcut on one line and it is saved.
Ctrl+VPaste a URL anywhere on the dashboard - pre-fills the new-bookmark form, or goes to the Inbox.
Shift+EInline-edit the highlighted bookmark. Ctrl+Enter saves, Esc cancels.
Shift+HHealth view. Shift+I for the Inbox, Shift+S for config.
! / F1The searchable cheat sheet. Everything else is in there.

Shortcuts that open sites

Give a bookmark a shortcut - GITHU, JELLY, TOWER - and typing it on the dashboard opens the site. No search box, no Enter. The project's own note: "a shortcut that needs Enter to finish is not much of a shortcut."

There is a real collision problem here, and nextDash handles it honestly. On an install with 200 shortcuts, eight of thirteen everyday words got swallowed mid-word by instant opening. So there are three modes under Config -> Behavior -> Search: open instantly (the default), open after a short pause, or require Enter. The default was changed to require Enter in one release and changed back in the next - "making Enter the default treated a rare collision as the normal case."

Overlays are properly modal

While search, the cheat sheet, quick-add or an inline edit is open, keyboard focus stays inside that overlay and the grid behind it is inert, not merely dimmed. That is the difference between a keyboard UI and a mouse UI with hotkeys bolted on.

The keyboard shortcuts overlay: a filter box above a grouped, searchable list of every shortcut, with the dashboard dimmed and inert behind it.
$ press ! or F1 - every shortcut, grouped and searchable
07

Search, commands and finders

Six entry points, one bar. The key you press decides what the bar searches.

KeyModeWhat it searches
>SearchThis page. Recent queries and saved searches appear as chips.
/Fuzzy searchRanked prefix -> word-boundary -> substring. Also matches URL domain, tags and note text.
@Global searchEvery page at once; each result shows which page it lives on.
:Command paletteFive collapsible groups - Bookmarks, Search & navigate, Look & layout, Smart collections, Settings & tools.
?FindersYour own web searches - "?g rate limiting" searches Google.
*RecentThe bookmarks you opened most recently.

The filter syntax

Typed straight into the search bar, with autocomplete after each prefix. A leading minus excludes instead of selects, so "tag:dev -status:pinned" is "dev links I have not pinned."

category:tag:page: status:online/offline/broken/okstatus:pinned/unpinned status:untagged/taggedstatus:feed/unfed added:today|week|month|yearopened:never

Your browser's address bar is a search box - v1.4.0

Type the keyword, Tab, a term, Enter, and you land in your bookmarks with the results already on screen. No extension, no dashboard to open first - your browser offers this after one visit. It works because a search now has an address of its own (#search?q=...), so it can be bookmarked or shared like any other view.

The search overlay: recent searches and recent commands as chips, a list of commands, filter syntax to search by, and a finders section.
$ the search overlay: recent queries, commands and filters, one keystroke away
08

Getting links in - by hand, and on their own

Saving has to be cheaper than not saving. Eight manual ways in, and - new in v1.4.0 - sources that keep bringing links in without you asking.

By hand

on the dashboard

Quick add & paste

& takes name | url | shortcut. Ctrl+V pastes a URL anywhere on the grid.

chrome & chromium

Browser extension

Pick page, category, tags and note - or save with your last-used defaults.

everywhere else

Bookmarklet

Built for you under Config -> Help -> Inbox, token filled in. Works in Safari, Firefox and mobile browsers.

phone

Share sheet

Install nextDash as an app and it appears in your phone's share sheet. An Apple Shortcut covers iOS Safari.

launchers

Raycast, Alfred, Ulauncher

Type a URL, or save the front browser tab.

scripts

One shell line

./shell/nextdash-add "https://..." "A title", or GET /add?url=...&title=... directly.

The whole integration contract is one route

Every one of those tools talks to GET /add?url=...&title=.... Two environment variables configure them: NEXTDASH_URL and NEXTDASH_TOKEN - give it NEXTDASH_CAPTURE_TOKEN, which opens capture and nothing else. In the project's own words: "anything that can open a URL or run curl is an integration."

On their own - Sources - v1.4.0

Config -> Data & backups -> Sources is for the places bookmarks keep arriving from, as opposed to the import buttons above, which read a file once. A source remembers what it already brought in and previews what it would write before writing it.

Need a token

GitHub stars and Raindrop.io.

Need nothing at all

Hacker News, YouTube and Mastodon - type a username or channel and that is the whole setup.

Import a browser's own bookmark file and - since it is the format Pocket, Pinboard, Raindrop, linkding, Shiori, Linkwarden and Karakeep all export - those come along for free. Export bookmarks (HTML) sits beside the CSV pair, and reads back into any browser.

What happens when you save something twice

Saving a URL already on the same page is refused. A copy on another page becomes a question instead: nextDash names the page and category it is already filed under, offers to open it, and "Save anyway" keeps the second copy - the add form, quick add, the extension and every Source all ask it the same way.

09

The Inbox

A holding area for links worth keeping before you know where they belong. The point is that deciding later is a legitimate answer.

Shift+I or 0 opens it. Filter All / Unread / Snoozed / With note, search, and sort - the default is oldest first: "oldest-first is how a backlog actually clears, since the links you have been avoiding are at the bottom."

Snooze z

Three hours, tomorrow, the weekend, next week, or a date of your own. Left out of every count except Snoozed.

Promote p

Opens the full bookmark form pre-filled. The inbox entry disappears once the bookmark is saved - not before.

Triage t

One link at a time: j/k move, o open, p promote, r keep, d delete, Esc leave.

Import / export

CSV or JSON, both directions. Import skips duplicates and reports what did not fit.

The Inbox: a filterable, searchable list of links saved to read later, grouped by age, each with its source favicon and a short description.
$ Shift+I or 0 - everything waiting for a decision, oldest first

A backlog you can actually clear - v1.4.2

Triage used to hand you everything the filter showed, including what you had already read, and looped silently back to the start instead of ending. It now walks only the unread, closes with "that is the lot" once you have, and promoting a link no longer kicks you out of triage - so clearing forty links is forty presses of p, not forty separate trips back in.

Every count follows the active filter, and "Mark all read" honestly renames itself to "Mark shown read" when the view is narrowed.

10

Health: link rot as its own subject

This is the part no other bookmark manager has, and the reason nextDash was built.

The Health page: a score and 24-hour trend line, filter counts for broken, stale, unused, missing-preview and expiring-certificate bookmarks, and a sorted list of bookmarks that need attention - here catching a self-hosted service that has been timing out for over a week.
$ the Health view: every bookmark, sorted by what needs attention

Three levels of checking

ModeWhat it does
OffNever checked. The right answer for most bookmarks.
PeriodicChecked in the background on the dashboard's own schedule.
MonitorChecked on its own interval (5 minutes to 24 hours, default 15) with 30 days of history behind it.
Configuration screen explaining the three availability-checking modes: Off, Periodic, and Monitor.
$ config: how checking works - off, periodic, or fully monitored, set per bookmark

What it can detect

Reachability

Status and ping time, with named causes: DNS, timeout, refused, TLS, redirect or content.

Expectations

Text a page must contain, and which status codes count as healthy - "a site that answers 200 while showing 'Database connection failed' is up by every ordinary measure."

A bot check is not a dead link - v1.4.0

A site asking "are you a robot" used to be counted as gone. Only answers that actually say the page or host no longer exists count now; the rest read as unknown.

Drift

A page can answer 200 forever while stopping being the page you saved. Opt in and every check compares against a recorded baseline.

Certificates

Every monitored HTTPS check already completes a TLS handshake, so expiry costs nothing extra. Warnings at 30, 7 and 3 days.

Maintenance windows

Failures inside a scheduled window raise no alert and do not count against uptime.

Checking a service you have to be signed in to - v1.4.0

A self-hosted service bookmarked at its web interface used to answer "not signed in" to an anonymous check, so the row read broken while the service was fine. Store the sign-in once under Config -> Data & backups -> Sources -> Health sign-ins and point any number of bookmarks at it. The secret stays out of your backups unless you ask for it, and is dropped at the boundary if the service redirects the check elsewhere - the check goes on anonymously rather than handing your credential to a third-party address.

Uptime that does not flatter itself

A monitored bookmark detail view: 100% uptime over 24 hours and 7 days, 99.8% over 30 days, a response-time chart, a heartbeat bar, and a recent-outages log with a CSV export button.
$ a monitored bookmark: uptime history, response time, heartbeat, CSV export

Uptime pools individual checks rather than averaging per-monitor percentages. Every percentage carries the number of checks behind it: "100% from three checks is a weaker claim than 100% from three hundred." Days you did not open the dashboard leave a gap rather than a straight line through them.

Getting told

A downtime alert fires after N consecutive failures (default 3) and again on recovery.

SlackDiscordTelegramGotifyntfyPushoverraw JSON

Buttons on a downtime alert - v1.4.0

An alert reaching your phone through ntfy now carries Open link and Health buttons, so you can act on it without finding a laptop. Give nextDash its own address under Config -> Behavior -> Status -> Downtime alerts for the second button to work.

Tell it to leave one alone - v1.4.2

A bookmark you have already looked at and judged - yes it is stale, leave it - used to raise the same flag on every single check. Press n or z on a row, or use the row menu, and that one condition is set aside; the bookmark keeps being checked, only that flag stops firing. An Ignored filter lists everything you have put aside, and one click brings a bookmark back.

Working the list

  • Ten links, two minutes - a corner card names what is waiting and runs "Work through" over the worst ten.
  • The rot report - sums up what has gone or moved, readable grouped by site.
  • Repair, not just diagnosis - follow redirects in one action after a domain move, or point a dead link at its last Web Archive capture.
11

Widgets: the dashboard holds more than links now

The largest new feature in v1.4.0. A block on a page can now hold something other than links.

A widget sits among your categories, is dragged into place like one, and can be one or two columns wide. It shares the same ordering list as categories, so there is one answer to where anything sits on the page. Add, name and arrange them under Config -> Widgets, which grew out of a list it started in under Pages & tags and now has its own place in the rail under Data & backups.

A dashboard page with three widgets among the categories: a Health trend line chart, an Uptime widget listing monitored bookmarks with their status, and an Inbox widget showing saved, filed and kept counts.
$ three widgets on one page: health trend, uptime, and the inbox count

Twenty built-in tiles, plus one you build yourself

Grouped in the catalog by the question each one answers.

Are the links still good?

WidgetReads
HealthThe figures the health view reports: broken, down, changed, fine. Click a figure to open that filter.
UptimeYour monitored bookmarks, worst first, with a heartbeat bar per row.
CertificatesCertificates about to expire, grouped by host rather than by bookmark.
Health trendBroken links over time as a line, because the direction is what a single number cannot show.

What is arriving?

WidgetReads
InboxHow much is waiting to be filed, and how long the oldest has waited.
FeedsFeeds with new items, and the ones that stopped after repeated failures.
SourcesWhat each import last did, so a failed import is not only visible in config.

What needs tidying?

WidgetReads
NeglectedBookmarks you saved and have not opened, oldest first.
Blind spotsNever checked, checked long ago, or not watched at all.
DuplicatesThe same address stored more than once, and how many copies could go.
ArchiveHow many bookmarks have a copy kept, and which broken ones have none.
TrashWhat is waiting there, and when retention removes it.
BackupsHow old the newest automatic backup is, and whether the last run failed.

How is this machine doing? - v1.4.8

The only four that read something outside nextDash, and the only ones that need setting up - a mounted /proc, a named disk, or a read-only Docker socket, depending which you add.

WidgetReads
ProcessorHow hard the processor is working, and whether work is queueing up behind it.
MemoryHow much memory is really in use, against the total, with the file cache counted as the spare room it is.
DisksHow full each disk is, and how much room is actually left on it.
ContainersHow many containers run, how many do not, and which have a failing healthcheck.

What's happening around you? - v1.7.0 / v1.7.1

WidgetReads
WeatherCurrent conditions beside a forecast, for the location the header already reads.
CalendarWhat is coming up, from the ICS feed set in Behavior -> Date & weather.
RSSThe latest articles from the feeds you give it - headlines, with the whole entry on hover.

Custom

The escape hatch, for a service that is not in the list: point it at an address that answers with JSON, name the fields, and it draws them - with 28 self-hosted services already filled in, from Sonarr and Plex to Pi-hole, Proxmox and Home Assistant. Can use the same stored sign-in as a health check, so no key ever reaches your browser.

The Add a widget catalog, scrolled to its later groups: the tail of what needs tidying (Archive, Trash, Backups), then how is this machine doing (Processor, Memory, Disks, Containers), then what is happening around you (Weather, Calendar, RSS).
$ config -> widgets -> add: the catalog runs to twenty tiles now, grouped by question
A Custom widget being configured for Sonarr: address, refresh interval, an API key sign-in, and three figures to read - in queue, downloading, unknown - with a Try it panel below.
$ a Custom widget pointed at Sonarr - three figures read straight from its API

Every widget has its own settings - which page it counts, how many rows, what it is called, how wide. A tile that leaves rows out now says how many, so five of twelve no longer looks like five of five. A figure on a tile opens the rows behind it, and a tile redraws from fresh data the moment its settings change.

Widgets you can operate - v1.4.2

Right-click a widget's title for rename, one or two columns, fold, settings and close - close means disable, not delete, so the widget and its settings survive being put away. Arrow keys step through its rows, Enter opens the one under the cursor, and every menu action has a key of its own.

The Custom tile keeps itself current - v1.4.2

It now has a timer per widget instead of one shared tick, matched to what it is reading - every 60 seconds for a download client, every five minutes for a queue count, hourly for Speedtest Tracker. A Refresh now entry in its menu forces an update on the spot, and a hidden tab asks nothing until you come back.

12

Keeping a copy of a page

Everything else in the health view is diagnosis - it tells you a link is dead and offers whatever copy somebody else happened to take. For a page nobody else bookmarked, there usually is none.

v1.4.0

Ask the Web Archive

Keep a copy the day you save a link. Switch it on under Config -> Data & backups -> Sources, with an archive.org key pair and a one-page test capture to prove them.

v1.4.0

Keep a copy on your own disk

Local copies saves a whole page - text, styling and images - as one file, through monolith, so it stays readable even if the site and the Web Archive are both gone.

v1.4.0

A tab for what you have saved

Config -> Bookmarks -> Local copies lists them grouped by the bookmark they belong to, since the question is almost always "what do I have of this page".

Local copies are, by far, the largest single thing a backup can carry - Section 17 covers how that stays opt-in.

13

Collections, tags and Fresh

Three ways the dashboard reorganises itself around what you actually do, without you filing anything.

Today (your keyword sets), Recently opened, Most used, Stale, Recently added (off by default), Fresh (bookmarks whose site published something new), one collection per tag, and your own rules on category, tag, page, status, pinned, untagged, or days since last opened.

Fresh

Switch it on and nextDash reads the head of every page you have saved, notes any RSS or Atom feed advertised there, and polls what it found hourly. "Not a feed reader - no articles are stored, only how many entries are newer than your last visit, because otherwise this is a second product rather than a five-hundred-line feature."

Tags

Shift+T for a quick-tag popover, / for the word cloud, t to filter the grid to a bookmark's own tag.

A tag cloud overlay showing tags sized by how often they are used, on top of the dashboard - the selected tag is outlined.
$ tags as a word cloud, sized by how often you use them - click one to jump in

Cards that say more - v1.4.0

A preview card now shows who published a page, who wrote it and when, alongside the title and image it already had. For video providers, the card includes a player you can start without leaving the dashboard.

14

Make it look like yours

This is a page you look at every day. nextDash ships 114 built-in theme families - 228 variants counting light and dark - and a colour editor with contrast warnings.

Themes

114 built-in families, each with a dark and light variant - 228 in total: Absinthe, Andromeda Drift, Arctic Cyan, Aurora Glass, Bamboo Panda, Bio Abyss, Cerulean Skylark, Candy Pop and dozens more, each tagged by mood - neutral, cool, warm, high contrast, vivid. Random theme picks a different one on every refresh, or every view change.

Custom colours

A full editor at #config/colors: edit the packaged families, build your own, export and import them, see contrast warnings live.

Layout presets

Seven of them - Default, Compact, Cards, Terminal-ish, Masonry, Detailed List and Launcher (large favicon tiles).

Fonts

Seven UI presets: Source Code Pro (the default), JetBrains Mono, IBM Plex Mono, Inter, IBM Plex Sans, DM Sans, System UI.

The button bar

Five positions, per-button show/hide. Hiding a button leaves its shortcut working. Since v1.4.0, a new install starts with the bar in the corner rather than centred; anyone who has already chosen a position keeps it.

Branding & PWA

A custom title and favicon apply to the browser tab, the web app manifest, and the installed app's name and icon on your home screen.

The theme browser: a searchable grid of built-in theme swatches, each labelled with its mood - neutral, cool, warm, high contrast, vivid - and a light/dark toggle.
$ browse and preview every built-in theme without leaving config

Two hundred themes that no longer look alike underneath - v1.4.2

The backdrop pattern used to default to dots, and only a handful of themes said otherwise - so 200 of the 214 variants painted the same texture under different colours. Every family now names its own: hatch for paper and earth tones, grid for circuitry and steel, lines for screens and neon, dots for mist and water. Your own choice under Config -> Appearance -> Backdrop still overrides any theme.

Config, and not overwhelming you with it

Nine sections - Overview, Pages & tags, Bookmarks, Appearance, Behavior, Data & backups, Statistics, Help and About - each deep-linkable, with an At a glance panel showing how many settings differ from default, an Only changed filter above every tab, and Ctrl/Cmd+Shift+K to find a setting by name or by its current value.

Two smaller habits landed in v1.4.0: panels fold shut now and remember which were open, and slow actions show progress - refreshing every link preview is one request per bookmark, and it used to just sit there looking hung.

The Statistics overview tab: stat cards for bookmarks, pages, categories, tags, shortcuts, monitored and pinned counts, plus plain-language panels on what needs attention and how the collection is actually used.
$ config -> statistics: every count that matters, read back to you in plain language
15

Telling other programs

Everything up to here sends a link in. Since v1.4.0 nextDash can also push out, and let something else ask it questions.

Outgoing webhooks

Config -> Data & backups -> Webhooks. Five events: a bookmark added, changed or removed, and a monitored bookmark going down or coming back. A receiver can subscribe to all of them or to a few.

POST /your-endpoint
content-type: application/json
webhook-id: msg_2b7f...
webhook-timestamp: 1756253400
webhook-signature: v1,K5s0...
{"type":"bookmark.added","timestamp":"2026-08-27T09:30:00Z","data":{...}}

Signed with the Standard Webhooks scheme, so a receiver that already verifies those needs no special case. The id and timestamp are signed rather than merely sent: the id is how a receiver recognises a redelivery it already acted on, the timestamp is how it refuses one replayed a day later. The key is shown once, at save time. A failed delivery is retried twice with a growing gap; a 4xx is not retried. Endpoints are checked at save time and again at delivery - a receiver that answers "go and look over there" is not followed.

An assistant that can search your bookmarks

One MCP endpoint at POST /mcp, JSON-RPC 2.0, four tools: search the collection, look one bookmark up, list the tags in use, add a bookmark. Off until you switch it on - "it answers questions about every bookmark in the install, which is not something to add to a default install quietly." Origin is checked on every request, and adding a bookmark through it goes through the same handler the dashboard itself posts to - duplicate checks, URL validation and outgoing webhooks all still apply.

16

A note on trust

Your bookmarks are a map of what you care about. That map should live on your own disk - and the way a project handles that question tells you most of what you need to know about it.

Read this before you put it on the internet

nextDash is built for personal or small-team use on a trusted network. There are no user accounts. Do not expose nextDash directly to the public internet.

Three ways to run it safely

recommended

Private overlay network

Tailscale or another mesh VPN, so nextDash never gets a public listener at all.

alternative

Reverse proxy with auth

Traefik, Caddy or nginx, with basic auth, OAuth2 Proxy or SSO in front.

simplest

Local only

Bind to 127.0.0.1 and reach it over SSH port forwarding.

The API now answers this dashboard, not every page on the internet - v1.4.0

Before 1.4, cross-origin responses answered Access-Control-Allow-Origin: * - any site open in a tab could read your bookmarks from a nextDash whose address it could guess, since the read routes need no token. The default is now same-origin. The browser extension is unaffected: a Manifest V3 extension with host permissions gets cross-origin access from the browser itself. Set NEXTDASH_CORS_ORIGINS to an explicit allowlist for other tools, or =* to restore the old behaviour if you understand what you are opting back into.

Two tokens, two jobs

NEXTDASH_WRITE_TOKEN

Every destructive endpoint requires X-NextDash-Token. The dashboard injects it automatically in a browser.

NEXTDASH_CAPTURE_TOKEN

The two capture routes cannot send a header - "a phone's share sheet and a javascript: bookmark have no way to set one." This weaker token opens capture and nothing else.

Other safety details, several new in v1.4.0

  • A stored sign-in stays on the service it was stored for. A watched host that redirected a health check elsewhere used to send the credential wherever it was told; dropped at the boundary now.
  • A custom widget's address and key stay on the server. They used to come back to the browser with the rest of the page's layout.
  • A webhook cannot be talked into delivering somewhere else. Checked at save time, checked again at delivery.
  • SSRF defence at dial time for preview, ping, icon fetch and the health check-a-URL box, with IP pinning for ~2 minutes to close the DNS-rebinding window.
  • The data directory is not browsable - /data/ publishes data/icons/ and an uploaded favicon or font, and nothing else.

Analytics, and why they are off

Opt-in, off until you turn them on. When off, the tracker script is not emitted into the page at all - never downloaded, no request leaves your machine. When on, no bookmark names, URLs or search queries are ever sent; every number is rounded into a band (500+, never 1274). DISABLE_TELEMETRY=true removes the choice from users entirely, server-wide.

17

Your data, and getting it back out

There is no database. Your entire installation is a folder of JSON files you can read in a text editor, copy to a USB stick, or put in git.

data/
├── bookmarks-1.json    one file per page: the page, its categories, its bookmarks
├── settings.json       every setting, saved searches, collections, theme choice
├── colors.json         your custom themes
├── finders.json        your web search providers
├── inbox.json          captured links waiting for triage
├── trash.json          deleted bookmarks, kept 30 days
├── health-history.json uptime samples - 30 days raw, 90 days of daily rollups
├── health-trend.json   one point per day, 90 days
├── webhooks.json       endpoint URLs and signing keys, mode 0600 - v1.4.0
├── icons/              fetched and uploaded favicons, content-named
├── local-copies/       saved page snapshots - v1.4.0
└── auto-backups/       rotating ZIPs, 3 by default (1-50)

A backup now carries your whole data directory - v1.4.0

Files used to be left out one at a time, each for a reason that held on its own - until together they made a restore an install that had lost its history and had to earn it back over weeks. Uptime alone needs thirty days before its chart means anything. Two switches under "What a backup carries" let you leave out the two largest or most sensitive things: local copies (by far the largest single thing in a backup) and stored tokens - including them means a restore needs nothing typed in again, and that the backup file is itself a secret.

Exports for every part

All bookmarks as CSV or, new in v1.4.0, as browser-compatible HTML that reads back into any browser. Inbox as CSV or JSON. Health state as CSV, and the individual up/down checks behind an uptime percentage as their own CSV.

Trash, for thirty days

Deleted bookmarks stay recoverable for 30 days with search and bulk restore.

18

Configuration reference

Everything that has to be decided before startup is an environment variable. Sources, widgets, webhooks and MCP all live entirely in the UI.

VariableDefaultWhat it does
PORT8080HTTP listen port, validated 1-65535 at boot.
NEXTDASH_DATA_DIR./dataWhere pages, bookmarks, settings and uploads live.
NEXTDASH_WRITE_TOKENunsetRequire X-NextDash-Token on write and destructive APIs.
NEXTDASH_CAPTURE_TOKENunsetSecond, weaker token for /add and /share only.
NEXTDASH_CORS_ORIGINSunset (same-origin)Extra Origin allowlist. Extension origins always allowed; * restores the pre-1.4 open default.
NEXTDASH_ACTIVITY_LOGmutate,statusoff, mutate, status, open, security.
NEXTDASH_ACTIVITY_LOG_PERSISToff1 rotates activity.log in the data dir.
NEXTDASH_OUTBOUND_REQUESTS_PER_MIN120Rate limit for all server-side outbound fetches.
NEXTDASH_SSRF_API_RATE_PER_MIN60Rate limit for preview, ping and icon APIs.
NEXTDASH_CSPonoff disables Content-Security-Policy headers.
NEXTDASH_AUTO_BACKUP_KEEP3How many automatic backups to keep (1-50).
DISABLE_TELEMETRYunsetServer-wide analytics kill switch.
DISABLE_NEWS_FEEDunsetServer-wide switch for the nextdash.cc news feed.

A recommended LAN or VPS block

environment:
  - PORT=8080
  - NEXTDASH_WRITE_TOKEN=change-me-to-a-long-random-string
  - NEXTDASH_CORS_ORIGINS=https://dash.example.com,chrome-extension://your-extension-id
  - NEXTDASH_ACTIVITY_LOG=mutate,status,security
  - NEXTDASH_ACTIVITY_LOG_PERSIST=1
19

What nextDash deliberately is not

A short list, because knowing where a tool stops is more useful than another page of features.

  • Not multi-user. No accounts, no roles, no permissions. Authentication is somebody else's job.
  • Not a cloud service. No sync server, no hosted tier, no account to lose access to.
  • Not a feed reader. Fresh counts what is new; it does not store or show articles.
  • Not a read-later app, even with local copies - a snapshot for when the original disappears, not a reading queue.
  • Not a general automation platform. Webhooks and MCP tell other tools what changed and answer questions about your bookmarks - not a workflow engine.
  • Not browsable data. The data directory serves icons and an uploaded font, and nothing else.
  • Not precious about its own decisions. The Enter-to-open default was introduced in one release and reverted in the next, with the measurement that justified it printed in the changelog.
20

Where to go next

Roughly three days from installed to habitual.

  1. Day one - get it populated

    Import your bookmarks (browser export, or a Source if one of the five fits), delete what you have not opened in two years, and put your ten most-used sites on page one with shortcuts.

  2. Day two - set it as your home page

    Install it as an app on your phone, add the browser extension, and set your browser's address-bar keyword so a search is one keystroke away.

  3. Day three - switch on health, and try a widget

    Set your most important bookmarks to Periodic, your self-hosted services to Monitor, and drop a Health or Uptime widget on your main page.

docs

The full manual

github.com/jordibrouwer/nextdash

reference

The cheat sheet

164 shortcuts, searchable in-app with ! or F1, and printable as a PDF from the repository.

news

Site and devlog

nextdash.cc for the project, readable inside the app under Config -> Overview.

Standing on shoulders. nextDash is based on ThinkDashboard by MatiasDesuu, and released under the MIT licence. Written in Go 1.24 with two dependencies, gorilla/mux and golang.org/x/net.

online uptime 53d 19 posts utf-8 wp 7.1.2