skim

command module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 18, 2026 License: MIT Imports: 19 Imported by: 0

README

skim

Preview how a link looks when shared on social media — including localhost — without deploying.

skim extracts OpenGraph / Twitter / standard meta tags from any URL and renders realistic preview cards for Facebook, Twitter/X, LinkedIn, Discord, and Slack, plus validation diagnostics and a raw meta-tag grid.

skim previewing a link across Facebook, Twitter/X, LinkedIn, Discord, and Slack, with diagnostics and a raw meta-tag grid

The cards are approximations of how each platform renders a shared link — not pixel-perfect reproductions. Exact appearance varies by platform, client, and device, and shifts over time as the platforms change. Use skim to sanity-check your tags and layout, not to match a specific platform down to the pixel.

Install

With Go installed (1.26+):

go install github.com/Seismix/skim@latest

The UI ships prebuilt and embedded, so there's no Node toolchain to install. This drops a skim binary in your $GOBIN (usually ~/go/bin, or %USERPROFILE%\go\bin on Windows) — make sure that's on your PATH.

Quick start

Run it:

skim

It starts a local server on a free port and opens your default browser. To pre-fill and auto-preview a URL:

skim http://localhost:3000

(Building from source instead? The binary lands at ./dist/skim — see Building.)

You can type a bare host — reddit.com becomes https://reddit.com, while localhost:3000 (and 127.0.0.1, *.localhost) becomes http://….

Flags: --port N (fixed port), --no-open (don't launch the browser), --user-agent "…". skim binds loopback (127.0.0.1) only — it's a personal local tool. Press Ctrl+C to stop — the listener closes and the port frees.

By default skim sends the OpenGraph crawler User-Agent (facebookexternalhit), since many sites serve share metadata only to recognized crawlers — Reddit, for example, returns an anti-bot page otherwise. This makes skim see what Facebook / Discord / Slack see. Override with --user-agent.

Why a local server at all?

The localhost feature dictates the architecture. A browser page can't fetch() an arbitrary origin's raw HTML (CORS + mixed content), so skim does the fetch on your machine and hands the parsed result to the UI. That fetch resolving to your localhost is why skim runs locally instead of as a hosted site.

skim binary
├── GET  /             → serves the embedded Svelte UI (web/dist)
├── POST /api/fetch-og → fetches the URL on THIS machine, parses meta, returns JSON
└── GET  /api/img      → proxies a preview image same-origin, so browser tracking
                          protection / hotlink checks don't block it

Building

Building needs Go and pnpm (used only to build the UI; the shipped binary has no runtime deps).

make           # build the Svelte UI, then the native binary → dist/skim
make dist      # build the UI, then cross-compile static binaries for win/mac/linux → dist/
make web       # build just the Svelte UI → web/dist
make run ARGS="http://localhost:3000"   # build, then run the binary serving the built UI

The Svelte UI is compiled by Vite to static assets and embedded into the binary via go:embed, so distribution is still a single file. Cross-compilation needs no extra setup — Go's GOOS/GOARCH plus CGO_ENABLED=0 produce fully static binaries.

Developing the UI

For live frontend work with hot-reload:

make dev        # or: cd web && pnpm dev

This starts the Vite dev server (HMR for web/src/**) and automatically builds and runs the Go backend, proxying /api to it, so the UI is fully functional while you edit. Vite prints the local URL (e.g. http://localhost:5173); Ctrl+C stops both and frees the backend port. Only the UI hot-reloads — main.go changes need a dev-server restart.

Tech stack

Layer Technology
Server + CLI Go (net/http, embed)
HTML parsing goquery
UI Svelte 5 + Vite + Tailwind CSS, built to static assets and embedded; Milk Interactive branding

Documentation

Overview

skim — a tiny, single-binary social-preview viewer.

It runs a local HTTP server that (1) serves the embedded UI and (2) fetches a URL *on this machine* and extracts its OpenGraph / Twitter / standard meta tags. Because the fetch happens locally, it can inspect http://localhost:* dev servers — the whole point.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL