Skip to content

Publishing

Once your extension is ready, you can package it and distribute it to other Stina users. This guide covers the full process from building to publishing.

Before publishing, ensure your extension builds cleanly:

Terminal window
pnpm build
pnpm typecheck # If you have type checking set up

The built output goes to the root of your extension directory (e.g., index.js).

Stina extensions are distributed as .zip files. A typical pack script (scripts/pack.js) creates a zip containing only the necessary files:

  • manifest.json
  • index.js (built output)
  • README.md (optional)
  • LICENSE (optional)

Add to your package.json:

{
"scripts": {
"pack-extension": "node scripts/pack.js"
}
}

Example scripts/pack.js:

import { createWriteStream, readFileSync } from 'fs'
import { join } from 'path'
import archiver from 'archiver'
const manifest = JSON.parse(readFileSync('manifest.json', 'utf-8'))
const filename = `${manifest.id}-${manifest.version}.zip`
const output = createWriteStream(filename)
const archive = archiver('zip', { zlib: { level: 9 } })
archive.pipe(output)
archive.file('manifest.json', { name: 'manifest.json' })
archive.file('index.js', { name: 'index.js' })
archive.finalize()
output.on('close', () => {
console.log(`Packaged: ${filename} (${archive.pointer()} bytes)`)
})

Don’t forget to add archiver as a dev dependency: pnpm add -D archiver

The recommended distribution method is via GitHub Releases:

  1. Create a GitHub repository for your extension
  2. Tag a release with the version number (e.g., v1.0.0)
  3. Attach the .zip file to the release
  4. Users can install by providing the GitHub repo URL in Stina’s extension manager
Terminal window
# Tag and create a release
git tag v1.0.0
git push origin v1.0.0

Then create a release on GitHub and attach your .zip file.

To make your extension discoverable in Stina’s built-in extension browser, you can submit it to the Stina Extensions Registry.

The registry is a simple registry.json file containing:

{
"extensions": [
{
"id": "my-extension",
"repository": "https://github.com/yourname/stina-ext-my-extension",
"category": "tools",
"verified": {
"1.0.0": "sha256-hash-of-zip-file"
}
}
]
}

To submit:

  1. Fork the registry repository
  2. Add your extension to registry.json
  3. Include the SHA256 hash of your release .zip
  4. Submit a pull request

Stina fetches full extension details (name, description, releases) directly from GitHub at install time — the registry only stores the minimum needed for discovery.

Follow Semantic Versioning:

  • Patch (1.0.x): Bug fixes, no new features
  • Minor (1.x.0): New features, backward compatible
  • Major (x.0.0): Breaking changes

Update the version in both manifest.json and package.json when releasing.

  • manifest.json has correct version, permissions, and contributions
  • Extension builds without errors (pnpm build)
  • Type checking passes (pnpm typecheck)
  • Tested locally in Stina (Settings > Extensions > Install from folder)
  • README describes what the extension does and how to configure it
  • .zip package contains only necessary files
  • Release tagged in git with matching version