Skip to content

Development setup ​

Nostube is one repository with npm workspaces and a Rust server (ADR 0004).

Layout ​

PathPackageWhat it is
apps/webnostubeThe web app behind nostu.be, the embed player, a Node server for the oEmbed and playlist APIs, and the Tauri desktop wrapper
apps/server(Cargo)Nostube Server: the self-hosted Rust server with relay, Blossom (Almond) and admin API. It embeds the site, the Studio and the embed player
apps/site@nostube/siteThe creator homepage the server serves; reads /api/config
apps/studio@nostube/studioThe server's admin interface, served under /studio/
packages/core@nostube/coreShared logic without React: Nostr client, media URL ladder, HLS loader, video event parsing, instance config, browser transcoding
packages/widgets@nostube/widgetsShared React components: player, video card, UI primitives
docsnostube-docsThis documentation (VitePress, with its own package.json)

The packages are internal and not published. Apps import their TypeScript source by subpath, for example @nostube/core/media-url-generator, never through a barrel file. ESLint keeps packages/core free of React and app code.

Prerequisites ​

  • Node.js 22 (the version CI uses) and npm
  • A Rust toolchain (stable), only for apps/server

Install all workspace dependencies once, from the repository root:

sh
npm ci

Running the apps ​

Web app ​

sh
cd apps/web
npm run dev

Vite serves the app on port 8080. To try the Node server, run npm run build and then npm run server:dev. It serves dist/ together with the oEmbed and playlist APIs on PORT (default 8080, so stop Vite first).

Site ​

The site needs an instance config. In development it either proxies /api/config to a running Nostube Server or builds one from environment variables:

sh
# against a running server
NOSTUBE_SERVER_URL=https://localhost:8443 npm run dev --workspace @nostube/site

# or without a server: one creator, read from public relays
NOSTUBE_DEV_CREATOR=<64-hex pubkey> NOSTUBE_DEV_RELAYS=wss://relay.example,wss://nos.lol \
  npm run dev --workspace @nostube/site

NOSTUBE_DEV_SEARCH=local turns on the site search.

Studio ​

The Studio talks to the admin API of a running server. NOSTUBE_SERVER_URL forwards /api, /admin and /upload to it:

sh
NOSTUBE_SERVER_URL=https://localhost:8443 npm run dev --workspace @nostube/studio

Server ​

The server embeds the built site, Studio and embed player at compile time (from apps/server/web/dist). Build them first, then run the server:

sh
scripts/build-server-web.sh
cargo run --manifest-path apps/server/Cargo.toml -- --data ./data --port 8443 --http-port 0

Without --origin, the first start uses the local-ca TLS mode: the server creates a private CA and serves HTTPS itself. local-ca currently runs only on macOS; on Linux, start with --tls proxy --origin https://<host> behind a TLS proxy. Run scripts/build-server-web.sh again after changing the site, Studio or embed player. First start, setup and TLS modes are described in Getting started and HTTPS and networks.

Documentation ​

sh
cd docs
npm ci
npm run docs:dev

npm run docs:build fails on dead links.

Tests and checks ​

WorkspaceCommand (from the repository root)
core, widgets, site, studionpm run lint --workspace @nostube/core (likewise typecheck, test; repeat --workspace for several)
webcd apps/web && npm run test (typecheck, ESLint, Vitest and production build)
serverscripts/build-server-web.sh, then cd apps/server && cargo test

The web app also has npm run typecheck, npm run format and npm run format:check. A pre-commit hook (Husky, installed by npm ci) runs lint-staged and the web, core, widgets and site checks.

Desktop releases ​

The desktop release workflow runs only when a version tag matching v*.*.* is pushed. It builds a GitHub Release from that tag with macOS DMGs (Apple Silicon and Intel), a Windows x64 NSIS installer and a Linux x64 AppImage and Debian package. macOS builds are ad-hoc signed (signingIdentity: "-"), not signed with an Apple Developer ID or notarized.

Contributing ​

  • Commits follow Conventional Commits (feat:, fix:, chore:) with subjects of at most 72 characters, for example feat: improve playlist paging.
  • Pull requests explain the motivation, link relevant issues or Nostr events, include desktop and mobile screenshots for UI changes, and list the tests you ran. Keep changes small and scoped.
  • Issues live in GitHub Issues.

Architecture notes and glossaries ​

Released under the MIT License.