npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@blindmikey/jotson

v1.1.6

Published

Zero-dependency, drop-in editor for a project's JSON data files

Readme

  • Finder-style columns - drill through your data with breadcrumbs, keyboard navigation, and browser back/forward across jumps.
  • Smart types - dates, datetimes, and colors get native pickers; images, videos, and URLs get live previews (including server-side link unfurling).
  • File uploads - point a key at local media, or upload straight from the editor: files land in your configured upload directory as collision-proof UUIDs and the site-relative path is stored. Includes unused-upload cleanup and directory migration.
  • References (opt-in) - string ids that resolve to objects across all your files: resolved labels in columns, a searchable picker, "referenced by" backlinks, and integrity guards that offer to update or clean references when ids are renamed or objects deleted. Enable in ⚙️ when your ids are globally unique.
  • Full structural editing - add/rename/reorder/duplicate/delete keys and items, auto-generated UUID ids, per-file undo/redo, and an inline fields overview per object.
  • Safe saves - every save shows a line diff for confirmation, preserves line endings for minimal git noise, and nothing touches disk until you say so.
  • Fuzzy search across every file (Ctrl+K), a syntax-highlighted raw view, dark/light themes, and a built-in update notice.

Install

Install once globally, then run jotson in any project:

npm i -g @blindmikey/jotson
cd your-project
jotson

Prefer zero-install? npx @blindmikey/jotson works too.

Drop-in usage

Copy this jotson/ folder into any project, then:

node jotson/server.mjs

Requirements: Node 18+. Nothing else.

There are no npm dependencies, the server uses only Node built-ins (including global fetch for link previews), and the UI runs on a vendored copy of Vue (vendor/vue.js, Vue 3.5, MIT license). No build step, ready to use out-of-the-box.

Configuration: jotson.config.json

JotSON looks for its config in your project's root as jotson.config.json (override the path with the JOTSON_CONFIG env var). In drop-in mode, a jotson.config.json inside the tool's folder also works if no project-root config exists.

{
  "jsonDir": "data/json",
  "publicDir": "public",
  "uploadDir": "media",
  "logo": "/assets/images/logo.svg",
  "logoLight": "/assets/images/logo_alt.svg",
  "title": "My Project",
  "labelFields": ["title", "label", "name", "id"],
  "references": true,
  "idFields": ["id"]
}

| Key | Meaning | Default | | --- | --- | --- | | jsonDir | Directory of editable .json files, relative to the project root | empty (= project root) | | publicDir | Static media root; served at /site/* so /… asset paths preview | public | | uploadDir | Where file uploads are stored, relative to publicDir (created on first upload). Changing it offers to move existing uploads along and update every path referencing them | empty (= the publicDir root) | | logo | Optional image path (relative to publicDir) shown as the header brand | null (shows title) | | logoLight | Optional logo variant for the light theme (e.g. dark-text version) | null (reuses logo on a dark chip) | | title | Text brand fallback and window title | JotSON wordmark | | labelFields | Priority-ordered fields used to name objects in columns/breadcrumbs | see above | | references | Opt-in id-based reference detection. Leave off for datasets whose ids aren't globally unique (e.g. per-file incrementing numbers), which would show spurious references. Unavailable in projects with files over 20 MB | false | | idFields | Field names that identify objects as reference targets | ["id"] |

All of this is also editable in-app via the ⚙️ panel (directory changes are validated server-side; saves go to the resolved config path). If no config file exists, the defaults above apply and the first ⚙️ save creates jotson.config.json in your project root.

Notes

  • Binds to 127.0.0.1 only; intended as a local dev tool, never a deployed service.
  • Built to stay responsive on multi-MB files: huge collections render in capped windows with "show more", value edits are recorded as deltas for undo, and dirty checking runs debounced off the typing path.
  • Saves are validated (must parse as JSON), shown as a line diff for confirmation first, and preserve each file's existing CRLF/LF line endings for minimal version-control noise.
  • Minified (single-line) files stay minified: you edit and diff in pretty-printed form, but saves write the file back as one line, preserving its format.
  • There is deliberately no backup system, the assumption is your data files live in git.
  • String id fields are auto-generated as UUIDs when adding/duplicating items.
  • Strings matching YYYY-MM-DD / ISO datetimes are treated as date/datetime types with native pickers and multi-format previews (RFC 3339, Unix, Unix ms, UTC, relative).
  • Strings that look like local media paths (/media/hero.png) are treated as the file type: still a plain string, but with an Upload button. Uploads are copied into the upload directory renamed to a UUID, and the stored value becomes the site-relative path (so the preview renders). Media-only allowlist, 100 MB cap.
  • Deleting a key never deletes the file it points to. Abandoned uploads are reclaimed via ⚙️ → "Scan unused uploads", which lists UUID-named media files nothing references (unsaved edits count as references) and deletes them only after confirmation. Files jotson didn't create are never touched.
  • References: a string equal to some object's id (configurable via idFields) is treated as the reference type - columns show the resolved label (→ Jane Doe), the inspector shows a target card with a go-to link, and a picker modal (search or browse collections) swaps the target. Works across files. Id-bearing objects list everything that references them as jump links, and browser back/forward retraces jumps and file switches. Renaming an id offers to update every reference to follow; deleting a referenced object warns and offers to clean the references up (array entries removed, key values blanked).
  • YouTube, Vimeo, Loom, Wistia, Dailymotion, Cloudflare Stream, and Bunny Stream URLs preview as playable embeds (direct .mp4/.webm links play natively); other external links show an OpenGraph preview card (title/description/image), fetched server-side and cached in memory.
  • Light/dark theme toggle in the top bar (persisted per browser).
  • Update notice: on load, the current version is compared against npm (one registry request per server run, skipped silently when offline). If a newer version exists, a green pill in the top bar shows it - click to copy the right update command for how you run JotSON.

Optional Environment variables

  • JOTSON_PORT: server port. Unset, the default 4400 is tried and, if busy, a free port is chosen automatically (printed at startup). Set explicitly, a busy port is an error.
  • JOTSON_ROOT: project root, if the jotson/ folder does not live directly inside it (default: the folder's parent; npx jotson sets it to the invocation directory)
  • JOTSON_CONFIG: explicit config file path (default: <project root>/jotson.config.json, falling back to the same name inside the tool's folder)