Search...Search plugins and themes...
⌘K
Sign in
  • Get started
  • Download
  • Pricing
  • Enterprise
  • Account
  • Obsidian
  • Overview
  • Sync
  • Publish
  • Canvas
  • Mobile
  • Web Clipper
  • CLI
  • Learn
  • Help
  • Developers
  • Changelog
  • About
  • Roadmap
  • Blog
  • Resources
  • System status
  • License overview
  • Terms of service
  • Privacy policy
  • Security
  • Community
  • Plugins
  • Join the community
  • Discord
  • Forum / 中文论坛
  • Merch store
  • Brand guidelines
Follow us
DiscordTwitterBlueskyThreadsMastodonYouTubeGitHub
© 2026 Obsidian

Modules

polyipseitypolyipseity6k downloads

Load JavaScript and related languages like TypeScript modules from the vault and the Internet.

Add to Obsidian
  • Overview
  • Scorecard
  • Updates15

Load JavaScript and related languages like TypeScript modules from the vault and the Internet.

Repository · Changelog · Community plugin · Related · Features · Installation · Usage · Contributing · Security

Trailer

For first time users, read the installation section first!

This file is automatically opened on first install. You can reopen it in settings or command palette.

Features

  • Load JavaScript and TypeScript modules from the vault and the Internet on all platforms.
  • Load modules at startup.
  • No configuration needed.
  • Resolves relative paths, vault paths, Markdown links, wikilinks, and external links.
  • Loads Markdown files as code.
  • Supports using other modules inside modules.
  • Loads CommonJS (module.exports) and ES modules (export).
  • Supports circular dependencies for CommonJS modules.
  • Configurable require name.
  • Adds source maps for debugging.
  • Supports popular plugins like Dataview and Templater.

Installation

  1. Install plugin.
    • Community plugins
      1. Install the plugin from community plugins directly.
    • Manual
      1. Create directory modules under .obsidian/plugins of your vault.
      2. Place manifest.json, main.js, and styles.css from the latest release into the directory.
    • Building (rolling)
      1. Clone this repository, including its submodules.
      2. Install bun. See https://bun.sh for installation.
      3. Run bun install in the root directory.
      4. Run bun run obsidian:install <vault directory> in the root directory.
    • Obsidian42 - BRAT (rolling)
      • See their readme.
  2. Enable plugin.
  3. (optional) Configure plugin settings.

Usage

  • Enable the plugin.
  • To import a module:
// Using `require.import` is recommended.
await self.require.import("obsidian") // builtin modules such as the Obsidian API
await self.require.import("vault/path/to/a module.md") // vault path
// The following three require context and may not be able to infer the current directory. Please file an issue if so. Context inference is only available for top-level code, i.e. not inside functions or classes.
await self.require.import("../relative/path/to/a module.js") // relative path
await self.require.import("[omitted or whatever](markdown/link/to/a%20module.js.md)") // Markdown link
await self.require.import("[[wikilink/to/a module|omitted or whatever]]") // wikilink
// The following one requires enabling external links in settings.
await self.require.import("https://esm.sh/scratchblocks") // external link
// You can workaround the inability to infer the current directory.
await self.require.import("../relative/path/to/a module.js", { cwd: context.currentDirectory })

// If `await` is not supported, use `require` instead. It has less support for loading modules, however.
self.require("obsidian")
self.require("vault/path/to/a module.md")
// The following three require context and may not be able to infer the current directory. Please file an issue if so. Context inference is only available for top-level code, i.e. not inside functions or classes.
self.require("../relative/path/to/a module.js")
// The following three may not work in startup scripts.
self.require("[omitted or whatever](markdown/link/to/a%20module.js.md)")
self.require("[[wikilink/to/a module|omitted or whatever]]")
// The following one requires enabling external links and adding the link to preloaded external links in settings.
self.require("https://esm.sh/scratchblocks") // external link
// You can workaround the inability to infer the current directory.
self.require("../relative/path/to/a module.js", { cwd: context.currentDirectory })
  • To use entities in a module:
const { eat, pi } = await self.require.import("[[module]]")
eat(2 * pi)
// OR
const mod = await self.require.import("[[module]]")
mod.eat(2 * mod.pi)
  • To create a module, create a JavaScript or related language file or a Markdown file with JavaScript or related language code blocks.
    • For require (but not require.import), the module file needs to be preloaded, which can be configured in settings. By default, preloaded files have the following extensions: .js, .js.md, .mjs, .mjs.md, .ts.md, .mts.md, .ts, .ts.md
    • Modules should not have global or side effects because they are cached and thus not reloaded on every requiring.
    • For Markdown files, code block languages that are loaded can be configured in settings.
    • For non-JavaScript languages, ensure the module file has the correct file extension (also applies to .xxx.md) or prepend the following metadata:
// { "language": "TypeScript" }

export const variable: string = "string"
---
module:
  language: TypeScript
---

```TypeScript
export const variable: string = "string"
```
  • Module exports can be CommonJS-style or ES module-style:
// ES module-style, supported by `require.import`.
export function fun() {}
export const variable = "string"
export default 42 // The default export has the name `default`.

// CommonJS-style, supported by both `require` and `require.import`.
module.exports.fun = function() {}
module.exports.variable = "string"
module.exports.default = 42
exports.abbreviatedForm = {}
  • To create a startup module, export a function (supports async) to run at startup using export default or assigning to module.exports and add the module to plugin settings:
// ES module-style
export default function() {
    console.log("Hello world!")
}

// CommonJS-style
module.exports = function() {
    console.log("Hello world!")
}
  • The full API is available from src/@types/obsidian-modules.ts.

Contributing

Contributions are welcome!

Changesets

This project uses changesets to manage the changelog. When creating a pull request, please add a changeset describing the changes. Add multiple changesets if your pull request changes several things. End each changeset with ([PR number](PR link) by [author username](author link)). For example, the newly created file under the directory .changeset should look like:

---
"example": patch
---

This is an example change. ([GH#1](https://github.com/ghost/example/pull/1) by [@ghost](https://github.com/ghost))

Linting, Commit, and Hooks

This project uses the following tools to ensure code and commit quality:

  • ESLint: Linting for TypeScript/JavaScript. Run with bun run check (lint only) or bun run fix (auto-fix lint issues).
  • Prettier: Code formatting. Run with bun run format (format all files) or bun run format:check (check formatting only).
  • markdownlint: Lints Markdown files. Run with bun run markdownlint or auto-fix with bun run markdownlint:fix.
  • commitlint: Enforces conventional commit messages. Used automatically on commit via Husky.
  • husky: Manages Git hooks. Pre-commit runs lint-staged and pre-push runs commitlint.
  • lint-staged: Runs linters on staged files. Markdown files are auto-fixed before commit.

Lint-staged note: The lint-staged configuration (.lintstagedrc.mjs) invokes formatter/linter binaries directly (for example prettier --write, eslint --cache --fix, markdownlint-cli2 --fix) so that the list of staged files is passed through to the tool. Invoking these via bun run would prevent lint-staged from forwarding filenames and cause the tool to operate on its default glob (or the entire repo). Use bun run format to format the entire repository when needed.

To set up locally:

  1. Run bun install to install dependencies and set up hooks.
  2. On commit, staged Markdown files will be linted and auto-fixed.
  3. Commit messages are checked for conventional format.

You can manually run:

  • bun run check — lint all code (no formatting)
  • bun run fix — auto-fix lint issues (no formatting)
  • bun run format — format all code with Prettier
  • bun run format:check — check formatting with Prettier
  • bun run markdownlint — check all Markdown files
  • bun run markdownlint:fix — auto-fix Markdown files
  • bun run commitlint — check commit messages in range

Configuration files:

  • .eslintrc.* or eslint.config.mjs — ESLint rules
  • .prettierrc — Prettier rules
  • .prettierignore — Prettier ignore patterns
  • .markdownlint.jsonc — markdownlint rules
  • .commitlintrc.js — commitlint config
  • .husky/ — Git hooks

Testing

This repository uses Vitest for fast unit tests. Tests live under tests/ and should be named *.spec.ts or *.spec.js.

  • Run locally (non-interactive, coverage): bun run test (runs vitest run --coverage).
  • Run locally (interactive / watch): bun run test:watch.
  • Git hooks: The pre-push hook runs bun run test (see .husky/pre-push) and will block pushes if tests fail.

See vitest.config.mts for minimal config and further instructions.

Todos

The todos here, ordered alphabetically, are things planned for the plugin. There are no guarantees that they will be completed. However, we are likely to accept contributions for them.

  • User-defined module aliases.
  • Add bare module transformation support for more CDNs such as https://cdn.jsdelivr.net.
  • Faster import analysis and transformation.
  • Autocomplete with JSDoc.

Translating

See assets/locales/README.md.

Security

We hope that there will never be any security vulnerabilities, but unfortunately it does happen. Please report them!

Supported versions

Version Supported
rolling ✅
latest ✅
outdated ❌

Reporting a vulnerability

Please report a vulnerability by opening an new issue. We will get back to you as soon as possible.

45%
HealthGood
ReviewRisks
About
Load JavaScript and TypeScript modules from your vault and the Internet on all platforms, treating Markdown files as loadable code. Resolve relative paths, vault paths, Markdown links, wikilinks and external URLs, and support CommonJS and ES modules, circular CommonJS deps, nested imports, and source maps for debugging.
ImportCodeDevelopers
Details
Current version
2.5.0
Last updated
Last year
Created
3 years ago
Updates
15 releases
Downloads
6k
Compatible with
Obsidian 1.4.11+
License
AGPL-3.0
Report bugRequest featureReport plugin
Sponsor
Buy Me a Coffee
GitHub Sponsors
Author
polyipseitypolyipseity
github.com/polyipseity
GitHubpolyipseity
  1. Community
  2. Plugins
  3. Import
  4. Modules

Related plugins

CustomJS

Reuse custom JavaScript across desktop and mobile.

CodeScript Toolkit

Allows to do a lot of things with JavaScript/TypeScript scripts from inside the Obsidian itself

Templater

Create and use dynamic templates.

Importer

Import data from Notion, Evernote, Apple Notes, Microsoft OneNote, Google Keep, Bear, Roam, and HTML files.

BRAT

Easily install a beta version of a plugin for testing.

Zotero Integration

Insert and import citations, bibliographies, notes, and PDF annotations from Zotero.

Readwise Official

Sync highlights from Readwise to your vault.

PlantUML

Generate PlantUML diagrams.

ZotLit

Integrate with Zotero, create literature notes, and insert citations from a Zotero library.

Kindle Highlights

Sync your Kindle book highlights using your Amazon login or uploading your My Clippings file.