Skip to content

Getting started

Requirements

Suggested knowledge

You don’t need to be an expert (or have worked) in the above subjects, but it makes creating extensions much easier. We believe in learning by doing, so don’t be afraid to ask for help in our Discord server or reference other extensions.

Reading how other extensions work can be a huge resource, so we encourage you to reference the moonlight core extensions and the extensions on the official repository if you’re stuck. Just remember to respect the licensing of the extension!

Setting up the sample extension

A sample extension is provided to start development quickly:

  • Pre-configured build system (esbuild)
  • TypeScript support
  • Example usage of Node.js code
  • Example patch & Webpack modules

It is configured like a monorepo, so multiple extensions can live in the same Git repository. This is not required.

You can view it here.

Set up the repository

On GitHub, click “Use this template” on the sample extension repository to create a new repository.

In the repository settings, make sure GitHub Actions is enabled for this repository, and that the GitHub Pages source is set to GitHub Actions:

  • GitHub Actions: “Code and automation” > “Actions” > “General” > “Actions permissions”
  • GitHub Pages: “Code and automation” > “Pages” > “Build and deployment” > “Source”

Clone the repository with your favorite Git client.

Clean up the sample extension

First, remove the files that aren’t needed:

  • Delete README.md, and optionally replace it with your own.
  • Modify LICENSE if you would like to use a different license. moonlight is licensed under the GNU Lesser General Public License (LGPL-3.0-or-later).

Next, decide what you’ll rename everything to:

  • Pick a name for your extension. This will be displayed to the user in Moonbase. We suggest a short but informational one.
  • Pick an ID for your extension. We suggest using the name of your extension in camelCase:
    • Context Menu -> contextMenu
    • Moonbase -> moonbase
    • No Hide Token -> noHideToken

Now, change the branding of the extension:

  • Change the name in package.json.
    • If your repository will just have one extension in it, set it to the extension ID.
    • If your repository will hold multiple extensions, we suggest picking a generic name like moonlight-extensions.
  • Rename the sampleExtension folder in src to your extension ID.
  • Change the meta field in manifest.json:
    • Change name to your user-facing extension name.
    • Change tagline to a short explanation of your extension.
    • Change or delete description to a longer explanation of your extension. If you have any important notes about the extension’s functionality, add them here.
    • Change authors to contain your username.
    • Change source to the URL of your Git repository.
  • Replace all uses of sampleExtension with your extension ID in the following files:
    • manifest.json
    • index.tsx
    • webpackModules/entrypoint.ts
    • env.d.ts (located at the root folder)

Build and run the extension

  • Install dependencies: pnpm i
  • Build the extensions: pnpm run build
  • Build in watch mode, so your extension is built when you make changes: pnpm run dev
    • This command will need to be restarted if you edit the extension manifest, add/remove an entrypoint, or add/remove a Webpack module.
    • If you delete an extension, entrypoint, or Webpack module, you should run pnpm run clean to clean up the remaining build output.

Use the “Extension search paths” setting in Moonbase (or set devSearchPaths in your moonlight config) to add the dist folder next to your code. If you don’t have a dist folder, you need to build the extension first.

After restarting your client, the extension will load.

What’s next?

Congrats on making it this far! There’s a lot more to learn about how moonlight works:

If you need any help, don’t be afraid to ask in our Discord server.

Publishing to GitHub Pages

Your repository will be published to https://<username>.github.io/<repository>/repo.json. Every time a commit is made to the main branch, the extensions will be built on GitHub Actions and published automatically.

It is suggested to only use this if you do not plan to submit to the official repository. You can also delete the .github/workflows/deploy.yml file if you do not want this (or if you aren’t using GitHub).