Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/meteor/meteor/llms.txt

Use this file to discover all available pages before exploring further.

Meteor packages are the primary way to extend Meteor’s functionality. This guide covers creating and publishing both core and community packages.

Package Structure

Every Meteor package requires a package.js file that defines metadata, dependencies, and files.

Basic Package.js

package.js
Package.describe({
  name: 'username:packagename',
  version: '0.0.1',
  summary: 'A brief description of your package',
  git: 'https://github.com/username/package',
  documentation: 'README.md'
});

Package.onUse(function(api) {
  api.versionsFrom(['2.3', '3.0']);
  api.use('ecmascript');
  api.mainModule('main.js');
});

Package.onTest(function(api) {
  api.use('ecmascript');
  api.use('tinytest');
  api.use('username:packagename');
  api.mainModule('tests.js');
});

Core Package Example

Here’s a real example from packages/tracker/package.js:
Package.describe({
  summary: "Dependency tracker to allow reactive callbacks",
  version: '1.3.4',
});

Package.onUse(function (api) {
  api.use("ecmascript");
  api.addFiles("tracker.js");
  api.export("Tracker");
  api.export("Deps");
  api.addAssets("tracker.d.ts", ["client", "server"]);
});

Package.onTest(function (api) {
  api.use('tinytest');
  api.use('test-helpers');
  api.use('tracker');
  api.addFiles('tracker_tests.js', 'client');
});

Complex Package Example

From packages/mongo/package.js:
Package.describe({
  summary: "Adaptor for using MongoDB and Minimongo over DDP",
  version: "2.2.0",
});

Npm.depends({
  "mongodb-uri": "0.9.7",
  "lodash.throttle": "4.1.1",
});

Package.onUse(function (api) {
  api.use("npm-mongo", "server");
  api.use([
    "random",
    "ejson",
    "minimongo",
    "ddp",
    "tracker",
    "ecmascript",
  ]);
  
  // Weak dependencies
  api.use("insecure", { weak: true });
  api.use("autopublish", "server", { weak: true });
  
  api.export("Mongo");
  api.export("MongoInternals", "server");
  
  api.addFiles([
    "mongo_driver.js",
    "local_collection_driver.js",
  ], "server");
});

Package API Methods

Package.describe()

Package.describe({
  name: 'username:package',      // Required for published packages
  version: '1.0.0',              // Semantic version
  summary: 'Short description',  // Max 100 chars
  git: 'https://...',            // Git repository
  documentation: 'README.md'     // Documentation file
});

api.versionsFrom()

Specify compatible Meteor versions:
// Single version
api.versionsFrom('3.0');

// Multiple versions (Meteor 2 and 3)
api.versionsFrom(['2.3', '3.0']);

api.use()

Declare package dependencies:
// Single package
api.use('ecmascript');

// Multiple packages
api.use(['tracker', 'reactive-var']);

// Platform-specific
api.use('webapp', 'server');
api.use('tracker', 'client');

// Weak dependencies (optional)
api.use('accounts-base', { weak: true });

// Unordered (load in any order)
api.use('my-package', { unordered: true });

api.addFiles()

Add source files to the package:
// Single file
api.addFiles('main.js');

// Multiple files
api.addFiles([
  'client.js',
  'server.js'
]);

// Platform-specific
api.addFiles('client.js', 'client');
api.addFiles('server.js', 'server');
api.addFiles('both.js', ['client', 'server']);

api.mainModule()

Specify the main entry point (recommended over addFiles):
// Single entry point
api.mainModule('index.js');

// Platform-specific
api.mainModule('client/index.js', 'client');
api.mainModule('server/index.js', 'server');

api.export()

Export symbols globally:
// Export to client and server
api.export('MySymbol');

// Platform-specific export
api.export('ServerOnly', 'server');

// Multiple exports
api.export(['Symbol1', 'Symbol2']);

// Test-only export
api.export('InternalAPI', 'server', { testOnly: true });

api.addAssets()

Add non-code assets:
api.addAssets('data.json', 'server');
api.addAssets('types.d.ts', ['client', 'server']);

Npm.depends()

Declare npm dependencies:
Npm.depends({
  'lodash': '4.17.21',
  'moment': '2.29.1'
});

Creating a Package

1

Create package structure

Use the Meteor command to scaffold a package:
meteor create --package username:packagename
cd packagename
2

Edit package.js

Update the package metadata and dependencies:
Package.describe({
  name: 'username:packagename',
  version: '0.0.1',
  summary: 'What your package does',
  git: 'https://github.com/username/packagename',
  documentation: 'README.md'
});
3

Write your code

Create your main module file:
main.js
export const greet = (name) => {
  return `Hello, ${name}!`;
};
4

Add tests

Write tests in your test file:
tests.js
import { greet } from 'meteor/username:packagename';

Tinytest.add('greet - returns greeting', function (test) {
  test.equal(greet('World'), 'Hello, World!');
});

Testing Packages

Local Testing

Test your package in a local app:
# Create test app
meteor create test-app
cd test-app

# Add local package
meteor add ../path/to/package

# Run app
meteor run

Running Package Tests

# Run tests for your package
meteor test-packages ./

# With modern test driver
meteor test-packages ./ --driver-package meteortesting:mocha

Testing from Meteor Checkout

When contributing to core packages:
# Test specific package
./meteor test-packages packages/tracker

# Test all packages
./meteor test-packages

Publishing Packages

Prerequisites

1

Ensure Meteor 3 compatibility

For Meteor 3 packages, specify the release:
api.versionsFrom('3.0');
2

Test thoroughly

Run all tests and verify functionality:
meteor test-packages ./
3

Write documentation

Create a comprehensive README.md with:
  • Installation instructions
  • Usage examples
  • API documentation

Publishing to Atmosphere

# Login to Meteor account
meteor login

# Publish for Meteor 3
meteor publish --release=3.0.3

# Publish for both Meteor 2 and 3
meteor publish
If you omit --release when publishing Meteor 3 packages, they may default to Meteor 2 compatibility and cause Fibers-related errors.

Version Bumping

Follow semantic versioning:
  • Patch (1.0.0 → 1.0.1): Bug fixes, no breaking changes
  • Minor (1.0.0 → 1.1.0): New features, backward compatible
  • Major (1.0.0 → 2.0.0): Breaking changes
For core packages:
  • Patch bump: Changes OK to release independently
  • Minor bump: Requires new Meteor release
  • Major bump: Major rewrite, requires new Meteor release

Core Package Contributions

When contributing to core Meteor packages:

Guidelines

  • Each package should stand separately
  • APIs should be consistent between client and server where possible
  • Prefer synchronous APIs (use Meteor.wrapAsync on server)
  • Don’t harm the new developer experience
  • Don’t preclude experts from advanced usage

Submitting Pull Requests

1

Propose your change

Create a Discussion to build consensus before coding
2

Wait for 'ready' label

Once labeled ready, leave a comment and start working
3

Include tests

All code changes must include tests
4

Bump version

Update version in package.js according to change type
5

Follow code style

Package Best Practices

Structure

  • Use api.mainModule() instead of api.addFiles() for modern packages
  • Organize code by feature, not by client/server
  • Use ES modules (import/export)

Dependencies

  • Minimize dependencies to reduce bloat
  • Use weak dependencies for optional integrations
  • Specify version constraints for stability

Exports

  • Only export public API symbols
  • Use testOnly: true for internal test helpers
  • Document all exported functions

Testing

  • Test both client and server code
  • Test integration with common packages
  • Include edge cases and error handling

Documentation

  • Clear README with examples
  • API reference for all exports
  • Changelog for version updates

Next Steps

Testing Guidelines

Learn how to write comprehensive tests

Release Process

Understand how Meteor releases work