Pre-AlphaMetaScript is in early design phase. The compiler is not yet available.Join Discord for updates
MetaScript

Publish Your First Package

Learn how to create, configure, and publish a MetaScript package to the registry.

Prerequisites

  • MetaScript compiler installed
  • GitHub account (for authentication)
  • Your package code ready

Package Structure

A minimal package looks like this:

my-package/
├── src/
│   └── index.ms          # Main entry point
├── build.ms              # Build config
├── package.json          # Package manifest
└── README.md             # Documentation

Configure package.json

{
  "name": "@yourname/my-package",
  "version": "0.1.0",
  "description": "A helpful MetaScript package",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
  "metascript": {
    "entry": "src/index.ms",
    "targets": ["js", "c"]
  },
  "keywords": ["metascript", "utility"],
  "author": "Your Name <you@example.com>",
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/yourname/my-package"
  },
  "files": [
    "dist/",
    "src/"
  ]
}

Required Fields

FieldDescription
namePackage name (scoped recommended: @user/pkg)
versionSemver version (0.1.0, 1.0.0, etc.)
metascript.entryMain MetaScript entry file
metascript.targetsSupported compile targets

Authentication

Login with GitHub

msc login

This opens your browser to authenticate via GitHub OAuth. Your token is stored locally in ~/.mscrc.

Verify Login

msc whoami
# Output: @yourname

Build Your Package

Before publishing, build for all supported targets:

# Build JavaScript output
msc build --target=js

# Build C output (optional)
msc build --target=c

# Build all targets
msc build --all

Validate Before Publishing

Check your package is ready:

msc pack --dry-run

This validates:

  • Required fields in package.json
  • Entry file exists
  • Build outputs exist
  • No sensitive files included

Publish

First Release

msc publish

Subsequent Releases

Update version in package.json, then:

msc publish

Or use the version command:

msc version patch  # 0.1.0 -> 0.1.1
msc version minor  # 0.1.0 -> 0.2.0
msc version major  # 0.1.0 -> 1.0.0
msc publish

Scoped Packages

Personal Scope

{
  "name": "@yourname/utils"
}

Organization Scope

{
  "name": "@myorg/shared-lib"
}

Create an organization at pkg.metascriptlang.org/orgs.

Access Control

Public Package (default)

msc publish --access=public

Private Package

msc publish --access=restricted

Private packages require a paid organization plan.

Best Practices

Semantic Versioning

Follow semver:

  • MAJOR: Breaking changes
  • MINOR: New features, backwards compatible
  • PATCH: Bug fixes

Write Good Documentation

Your README.md should include:

# Package Name

Brief description.

## Installation

\`\`\`bash
msc add @yourname/package
\`\`\`

## Usage

\`\`\`typescript
import { something } from "@yourname/package"
\`\`\`

## API

Document your exports.

## License

MIT

Include Type Definitions

MetaScript generates .d.ts files automatically. Ensure they're in your files array.

Test Before Publishing

# Run tests
msc test

# Try installing locally
msc add ./path/to/my-package

Unpublishing

You can unpublish within 72 hours of publishing:

msc unpublish @yourname/package@0.1.0

After 72 hours, contact support for removal.

Package Discovery

Once published, your package appears:

  • On the registry: pkg.metascriptlang.org/@yourname/package
  • In search: msc search <query>
  • In the docs site: /pkg/@yourname/package

Example: Publishing a Utility Library

// src/index.ms
export function slugify(text: string): string {
  return text
    .toLowerCase()
    .replace(/\s+/g, '-')
    .replace(/[^\w-]/g, '')
}

export function capitalize(text: string): string {
  return text.charAt(0).toUpperCase() + text.slice(1)
}

export function truncate(text: string, length: number): string {
  if (text.length <= length) return text
  return text.slice(0, length) + '...'
}
# Build
msc build --target=js

# Publish
msc publish

Next Steps