⚠️ mlld is pre-release
Join the discord if you have questions. Report bugs on GitHub.
mlld Registry
tldr
Publish modules to the mlld registry with mlld publish. First-time modules go through PR review. Updates publish directly. Authenticate with GitHub, ensure CC0 license, include required metadata. Registry hosted at github.com/mlld-lang/registry.
Publishing Your First Module
Prerequisites
- GitHub account - You'll authenticate via GitHub
- mlld CLI - Install via
npm install -g mlld - Module file - Your
.mldfile with frontmatter
Required Metadata
---
name: my-tool
author: yourname
version: 1.0.0
about: Brief description of what this does
needs: []
license: CC0
---
All fields required. License must be CC0.
Publish Command
mlld publish my-tool.mld
First time publishing:
- Authenticates via GitHub
- Validates module
- Creates source (Gist or uses your repo)
- Opens PR to mlld-lang/registry
- Automated review posts feedback
- Merge approval gives you publish rights
Authentication
First time:
mlld auth login
Opens GitHub OAuth flow. Grants:
gistscope - Create Gists for module sourcepublic_reposcope - Create PRs to registry
Check status:
mlld auth status
Logout:
mlld auth logout
Module Validation
Your module must pass validation before publishing:
Syntax Validation
- No syntax errors
- No reserved word conflicts
- Valid mlld directives
Export Validation
/exportdirective present (recommended)- Exported names exist as variables
- No duplicate exports
Import Validation
- Imports reference valid modules
- No circular dependencies
- Local imports for dev only
Metadata Validation
- All required fields present
- Author matches GitHub username
- License is CC0
- Version follows semver
Run validation locally:
mlld publish --dry-run my-tool.mld
Publishing Workflow
First-Time Module
Creates a pull request:
mlld publish my-tool.mld
- Validation - Checks syntax, exports, metadata
- Source Creation - Creates Gist or references repo
- PR Creation - Opens PR to mlld-lang/registry
- Automated Review - LLM reviews for:
- No hardcoded secrets
- Safe operations
- Real utility
- Proper licensing
- Manual Review (if needed) - Maintainer approval
- Merge - Module becomes available
- Publish Rights - You can update directly going forward
Module Updates
After first module is merged:
mlld publish my-tool.mld
- Version Bump - Prompts for patch/minor/major
- Validation - Same checks as first-time
- Direct Publish - No PR needed (if authenticated)
- Registry Update - New version available immediately
Version bump options:
patch- Bug fixes (1.0.0 → 1.0.1)minor- New features (1.0.0 → 1.1.0)major- Breaking changes (1.0.0 → 2.0.0)custom- Specify exact version
Force PR workflow:
mlld publish --pr my-tool.mld
Existing PR Detection
If you have an open PR:
mlld publish my-tool.mld
Options:
- Update existing PR
- Close and create new PR
- View PR in browser
Direct Publish via API
After your first module is merged, you can publish updates directly using the Registry API:
# Via mlld CLI (recommended)
mlld publish my-tool.mld
# Via API directly
curl -X POST https://registry-api.mlld.org/api/publish \
-H "Authorization: Bearer $TOKEN" \
-F "module=@my-tool.mld"
Authentication:
- Requires GitHub authentication token
- Must be module owner or maintainer
- Token obtained via
mlld auth login
Behavior:
- Skips PR workflow
- Publishes immediately
- Updates registry in real-time
- Records
publishedByfield with your GitHub user ID
Use cases:
- Quick bug fixes
- Patch releases
- Version bumps for existing modules
Force PR workflow:
mlld publish --pr my-tool.mld # Creates PR even if you have direct publish rights
Module Structure
Versioned Registry
Modules are stored with version history:
registry/
└── modules/
└── alice/
└── my-tool/
├── metadata.json # Core info, owners
├── 1.0.0.json # Version 1.0.0
├── 1.0.1.json # Version 1.0.1
└── tags.json # latest, stable, etc.
metadata.json
{
"name": "my-tool",
"author": "alice",
"about": "Brief description",
"owners": ["alice"],
"maintainers": [],
"created": "2024-01-01T00:00:00Z",
"createdBy": 12345,
"firstPublishPR": 123
}
{version}.json
{
"version": "1.0.0",
"needs": ["js", "sh"],
"license": "CC0",
"mlldVersion": ">=1.0.0",
"source": {
"type": "github",
"url": "https://raw.githubusercontent.com/...",
"contentHash": "sha256:abc123...",
"repository": {
"type": "git",
"url": "https://github.com/alice/repo",
"commit": "abc123",
"path": "my-tool.mld"
}
},
"dependencies": {
"js": {
"packages": ["lodash"]
}
},
"keywords": ["utility", "automation"],
"publishedAt": "2024-01-01T00:00:00Z",
"publishedBy": 12345
}
Key Fields:
- publishedBy - GitHub user ID of the publisher (numeric ID, not username)
- publishedAt - ISO timestamp when this version was published
- source.type - Source type:
github,gist, orprivate-repo - source.contentHash - SHA256 hash for content verification
- source.repository - Git repository metadata (for github/private-repo sources)
tags.json
{
"latest": "1.0.1",
"stable": "1.0.1",
"beta": "2.0.0-beta.1"
}
Module Source
GitHub Repository
If your module is in a git repo:
mlld publish my-tool.mld
Detects:
- Repository URL
- Current commit SHA
- Module file path
- Whether repo is clean
Source references the commit SHA, ensuring immutability.
Gist
If not in a repo:
Creates a GitHub Gist automatically:
- Public Gist with module content
- Versioned via Gist revisions
- Content hash for integrity
Private Modules
For private/internal modules, use local or custom resolvers. See resolvers.md.
Dependency Declaration
Runtime Dependencies
---
needs: [js, py, sh]
---
Types:
js- Browser JavaScriptnode- Node.js (fs, path, etc.)py- Pythonsh- Shell commands
Package Dependencies
Use the legacy format (CLI-generated via mlld add-needs):
---
needs: [js]
needs-js: lodash, axios
---
Command Dependencies
Use the legacy format (CLI-generated via mlld add-needs):
---
needs: [sh]
needs-sh: git, curl, jq
---
Note: The parser supports a structured format (packages: [...]) but the CLI currently only generates and validates the legacy comma-separated string format shown above.
mlld Module Dependencies
---
dependencies:
"@alice/utils": "^1.0.0"
"@company/auth": "latest"
---
Auto-Detection
mlld add-needs my-tool.mld
Analyzes your module and updates frontmatter with detected dependencies.
Version Management
Semantic Versioning
Follow semver (major.minor.patch):
- 1.0.0 - Initial release
- 1.0.1 - Bug fix (backward compatible)
- 1.1.0 - New feature (backward compatible)
- 2.0.0 - Breaking change
Version Tags
Publish with tags:
mlld publish --tag beta my-tool.mld
Users import via tag:
/import { @helper } from @alice/my-tool@beta
Common tags:
latest- Most recent stable (default)stable- Recommended versionbeta- Beta testingalpha- Alpha testing
Version Ranges
Users specify ranges in mlld-config.json:
{
"dependencies": {
"@alice/my-tool": "^1.0.0", // 1.x.x
"@bob/utils": "~1.2.0", // 1.2.x
"@eve/lib": ">=1.0.0 <2.0.0" // Range
}
}
Lock file pins exact versions.
Lock File (mlld-lock.json)
When you install modules, mlld creates mlld-lock.json to ensure reproducible imports. This file tracks exact versions and content hashes.
Lock File Schema
{
"lockfileVersion": 1,
"modules": {
"@alice/utils": {
"version": "1.0.0",
"resolved": "abc123def456...",
"source": "@alice/utils",
"sourceUrl": "https://registry.mlld.org/modules/@alice/utils/1.0.0",
"integrity": "sha256:abc123...",
"fetchedAt": "2024-01-15T10:00:00Z",
"registryVersion": "1.0.0"
}
}
}
Lock Entry Fields
version - The exact version installed (from registry version.json)
resolved - Content hash used for cache lookup (SHA256)
source - Original module specifier from your imports
sourceUrl - URL where the module was fetched from
integrity - Content hash for verification (sha256:...)
fetchedAt - Timestamp when module was installed
registryVersion - Version from registry metadata (only for registry modules)
Lock File Behavior
- Auto-generated - Created/updated by
mlld install - Version control - Commit to git for reproducible builds
- Never edit manually - Use CLI commands to update
- Registry-only validation - Lock file only enforces version matches for registry modules
Commands
Install from lock file:
mlld install # Installs exact versions from lock file
Update lock file:
mlld update @alice/utils # Updates lock entry for specific module
Check lock file status:
mlld outdated # Shows modules with newer versions available
Ownership & Permissions
Module Owners
After first PR merges, you become module owner:
- Can publish updates directly
- Can add maintainers
- Module namespaced under your GitHub username
Maintainers
Add collaborators to metadata.json:
{
"owners": ["alice"],
"maintainers": ["bob", "eve"]
}
Maintainers can also publish updates.
Organization Modules
Publish under org namespace:
---
author: company
name: auth-tool
---
Requires write access to @company in registry.
Review Process
Automated Review
LLM reviews check for:
- No secrets - API keys, tokens, passwords
- Safe operations - No arbitrary code execution
- Real utility - Solves actual problems
- Proper licensing - Must be CC0
- Accurate metadata - Matches functionality
Review posts as PR comment with:
- APPROVE - Ready to merge
- REQUEST_CHANGES - Issues to fix
- COMMENT - Needs human review
Re-review on Updates
Push new commits to PR:
- Webhook triggers new review
- Shows previous review status
- Focuses on changes since last review
Trusted Authors
Authors in allowlist skip LLM review:
- Module structure validated
- No security issues detected
- Auto-merges if CI passes
Common Issues
Validation Errors
Missing required fields:
Add all required frontmatter fields.
Author mismatch:
Author field must match your GitHub username.
License not CC0:
Only CC0 license accepted for registry.
Export not found:
Ensure /export lists match variable names.
Publishing Errors
Not authenticated:
mlld auth login
Version already exists:
Bump version or publish with new version number.
Import validation failed:
Fix import references or use --skip-validation (not recommended).
PR Issues
Review requested changes:
Address feedback and push new commit.
Conflicts with main:
Rebase or close and create new PR.
PR not found:
Check github.com/mlld-lang/registry/pulls.
Best Practices
Test locally first:
mlld my-tool.mld # Run as script
mlld publish --dry-run my-tool.mld # Validate
Use explicit exports:
/export { @publicAPI }
Version appropriately:
- Patch for bugs
- Minor for features
- Major for breaking changes
Document well:
---
about: Clear, concise description
keywords: [relevant, searchable, tags]
---
Keep modules focused:
One module, one purpose. Split large modules into multiple packages.
Declare dependencies:
mlld add-needs my-tool.mld
Test across mlld versions:
---
mlldVersion: ">=1.0.0"
---
Registry API
For advanced use cases, registry API available at registry-api.mlld.org:
Resolve Version
curl https://registry-api.mlld.org/api/resolve?module=@alice/my-tool
Direct Publish
curl -X POST https://registry-api.mlld.org/api/publish \
-H "Authorization: Bearer $TOKEN" \
-F "module=@my-tool.mld"
See API docs for details.
Migration Guide
From Local to Registry
- Add frontmatter with required fields
- Add
/exportdirective - Run
mlld add-needsto detect dependencies - Test locally:
mlld my-tool.mld - Publish:
mlld publish my-tool.mld
From Gist to Repo
- Move module to git repo
- Commit and push
- Publish update:
mlld publish my-tool.mld
Source automatically updates to repo reference.
Support
Issues: https://github.com/mlld-lang/registry/issues
Discussions: https://github.com/mlld-lang/mlld/discussions
Examples: https://github.com/mlld-lang/registry/tree/main/modules