Library / SDK
orgapp/orgajs avatar
orgapp/orgajs

orga: an org-mode parser that produces a unified AST in JavaScript

parse org-mode content into AST

658 stars62 forksJavaScriptMIT

At a glance

What is it?
Orga parses org-mode content into an abstract syntax tree in JavaScript, and because the tree is unified rather than proprietary, it drops into existing tooling for linting, transforming and rendering, with webpack, Vite, React, Astro and Next.js integrations around it. It suits web developers who want org-mode in a content pipeline, and it is a parser, not a full org implementation.
Who is it for?
orga suits a team that keeps its writing in org-mode and wants it to live in a JavaScript build pipeline, for example a documentation site or a content-driven frontend, because the unified AST means the standard remark and rehype plugins apply to org files the same way they apply to markdown.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Why org-mode outside Emacs

Orga is a flexible org-mode syntax parser. It parses org content into an AST, and it is written in JavaScript. The subtitle in the project header says it in four words: org-mode less than JavaScript.

The reasoning is stated plainly in the Why section. org-mode is described as simply a superior format than other more popular ones, but as mostly trapped inside Emacs. It was the number one reason for many people learning and using Emacs, and the argument is that it is too good to not share with the rest of the world, and that if it can run in JavaScript, it can run on anything.

That framing tells you what the project is and is not. It is a parser and a set of integrations. There is no claim of implementing Emacs, no agenda system, no refactoring machinery, no capture templates. What it offers is the document format, parsed into a tree, for use in a JavaScript environment.

The audience follows from that. It is for web developers and content pipeline engineers who write in org-mode, or who want to accept org files from people who do, and who need the result in a browser or a build step rather than inside a text editor.

The project is MIT licensed, with the licence in LICENSE.org, and the repository is a pnpm workspace with the packages directory holding the individual pieces. The last push was on 2026-10-14, the same day as the orga 5.0.0 release.

Unified is the decision that makes the ecosystem apply

The single most consequential design choice is that the orga parser is completely compatible with unified, which the project describes as an interface for parsing, inspecting, transforming and serializing content through syntax trees.

That compatibility is not a formality. Unified is the tree format that the remark and rehype ecosystems are built on, and the plugins those ecosystems provide are what turn a parsed document into a linted one, a transformed one, or an HTML page. The project names retext for linting for natural language and alex for correcting your writing as examples of what you get access to by being compatible, and points at a getting-started example that shows it.

The alternative design would have been a proprietary AST with its own plugin ecosystem. That is a defensible choice for some projects, but it means every transformation is written from scratch. Being a citizen of the unified ecosystem means the transformation work is already done by a large body of existing tools, and the org format gains features, such as syntax highlighting, that were written for other formats.

The repository layout supports this reading. The root devDependencies include unist-util-map and vfile, both core unified packages, and rehype-pretty-code and shiki, which are the standard syntax highlighting chain in that ecosystem. In other words, org content joins the same pipeline that markdown already passes through, and gets the same treatment downstream.

For anyone who has worked with remark, the learning curve is therefore low. The tree shapes are the ones you already know, and the plugin vocabulary is the same.

The package set: parser, build tooling and editor are separate

The workspace root package.json is private, marked as a module, and it is the workspace manifest rather than a published package. It names the packages you can depend on: @orgajs/orgx, @orgajs/react-cm, @orgajs/react-editor and orga-build, all declared as workspace references.

Two of those are about editing rather than parsing. @orgajs/react-editor is a React editor for org content, and @orgajs/react-cm pairs it with CodeMirror, which the dependency list makes clear with @codemirror/language, @codemirror/view, @codemirror/lang-javascript, @codemirror/theme-one-dark and @lezer/highlight. The @lezer/highlight dependency is a strong hint that the editor surface is a CodeMirror extension with its own syntax tree for highlighting, which is a different tree from the unified AST.

orga-build is the build tool, and it is used by the repository's own docs scripts. The root scripts include a docs script that runs orga-build and a docs:dev script that runs orga-build dev, which means the project's documentation site is itself built with its own tool. That is a good sign for a build package, since it is exercised daily by the project.

The published release list confirms the split. The tags are orga 5.0.0, orga-build 0.11.0 and oast-to-hast 4.6.1, all on 2026-10-14. oast-to-hast is the org AST to HTML AST converter, the piece that turns a parsed org tree into something a web renderer understands.

Note the version numbers. The core parser is at 5.x while orga-build is at 0.11.x, so the build tooling is a younger package with a less settled API than the parser.

Importing .org files directly into a build

The integrations are where the parser meets real projects, and the README documents one per ecosystem.

For webpack, @orgajs/loader is described as a webpack loader that made orga a native citizen of the webpack ecosystem, working smoothly coupled with plugins, with an example project provided. For Vite and Rollup, @orgajs/rollup is a plugin compatible with both, and it lets you import .org files directly in your project.

For React, the project shows something more interesting than a component library. You can render React components directly in an org file, using an export block, and the example in the README is a heading followed by a paragraph and then an export block containing JSX. The demonstration in the source is short, a div with a background colour, padding, a border and a box shadow, described as a box with shadow.

For content-driven sites the story continues in standalone repositories. Astro integration is maintained in a standalone repository at orgapp/orga-astro with the package @orgajs/astro. Next.js integration is likewise maintained in orgapp/orga-next with the package @orgajs/next, and there is a Next.js integration guide at orga.js.org/guides/next.

The pattern of shipping the framework integrations separately while keeping the core parser and the build tool in the main repository is sensible. The parser has to track org-mode's syntax, while the integrations have to track each framework's own release cycle, and coupling them would make the parser wait for Astro.

There is also a live playground at orga.js.org/playground, linked from the README example, where the same org snippet can be run in the browser without setting anything up.

Reading the README as an org file, and where the docs live

The project does something mildly clever with its own documentation. The README is an org file, README.org, and it uses org syntax throughout. Headings are written as stars with levels, the section titles use equals signs for emphasis, and the code examples are wrapped in begin_src blocks with the language named, as in the org block containing the React export example.

The same applies to the contributing file, CONTRIBUTING.org, which the Contribute section points to with a file link. The repository is therefore a live demonstration of the format it parses, and reading the README is itself a test of whether the parser handles the constructs the project uses.

The documentation site is built with orga-build, and the docs directory in the repository holds the source. The root scripts confirm the two entry points, a docs script and a docs:dev script.

The examples directory is the other place to start, and it is organised by integration: examples/getting-started, examples/webpack, examples/editor, examples/build and an examples/README.org. The README points at the collection of examples as the quick way to get started, and separately links the getting-started example as the demonstration of the unified integration.

The build system is pnpm with a pnpm-workspace.yaml and a pnpm-lock.yaml, and the root scripts use pnpm recursive filters over the packages directory, with the pattern './packages/*'. Formatting and linting are handled by Biome, with a biome.json at the root, a check script and a check:fix script, and the build script ends by running tsc in both clean and build modes followed by type-coverage, which is a deliberate check on how much of the codebase is typed.

The scripts in the root package.json are the working vocabulary of the repository, and the ones that matter for a newcomer are these:

json
		"build": "pnpm -r --filter './packages/*' --if-present run build && tsc --build --clean && tsc --build && type-coverage",
		"test": "pnpm run check && pnpm -r --filter './packages/*' --if-present run test",
		"docs": "orga-build",
		"docs:dev": "orga-build dev"

The build compiles every package in the packages directory that has a build script, then cleans and rebuilds the TypeScript projects and finishes with the type coverage check. The test script runs the Biome check first and then the per-package tests. The two docs scripts drive the documentation site, and the dev variant is the one that serves it locally.

The README does not publish an install command for consumers, so the entry point is the package names themselves: the core parser, orga-build and the integration packages such as @orgajs/rollup, @orgajs/loader and @orgajs/astro, each published under the @orgajs scope or under its own name. A project that wants org files in a Vite build adds the rollup plugin to its dependencies and imports .org files directly.

For a first pass, the examples directory is the fastest route: the getting-started example demonstrates the unified integration, the webpack example shows the loader in a real project, the editor example covers the React and CodeMirror packages, and the build example shows orga-build.

Building the workspace and running the docs site

The scripts in the root package.json are the working vocabulary of the repository, and the ones that matter for a newcomer are these:

json
		"build": "pnpm -r --filter './packages/*' --if-present run build && tsc --build --clean && tsc --build && type-coverage",
		"test": "pnpm run check && pnpm -r --filter './packages/*' --if-present run test",
		"docs": "orga-build",
		"docs:dev": "orga-build dev"

The build compiles every package in the packages directory that has a build script, then cleans and rebuilds the TypeScript projects and finishes with the type coverage check. The test script runs the Biome check first and then the per-package tests. The two docs scripts drive the documentation site, and the dev variant is the one that serves it locally.

The README does not publish an install command for consumers, so the entry point is the package names themselves: the core parser, orga-build and the integration packages such as @orgajs/rollup, @orgajs/loader and @orgajs/astro, each published under the @orgajs scope or under its own name. A project that wants org files in a Vite build adds the rollup plugin to its dependencies and imports .org files directly.

For a first pass, the examples directory is the fastest route: the getting-started example demonstrates the unified integration, the webpack example shows the loader in a real project, the editor example covers the React and CodeMirror packages, and the build example shows orga-build.

Versioning with changesets, and the maintenance picture

The release process is changesets based. The .changeset/ directory at the root is where change descriptions are written, and the root scripts expose the whole flow: a changeset script that creates one, a ci:version script that runs changeset version, and a ci:publish script that runs pnpm build and then changeset publish. There is a CHANGELOG.md as well.

This is a good sign for a library with several published packages, because changesets handles the version bump and changelog generation per package, which is exactly the problem you hit when a monorepo publishes a core parser and a build tool at independent rates.

The release history visible in the tags is short. orga 5.0.0, orga-build 0.11.0 and oast-to-hast 4.6.1 were all published on 2026-10-14, and the repository is not archived. The last push was on 2026-10-14 as well, so the project is at a 5.0 milestone for the parser and shipping three packages together.

Two housekeeping tools in the dependency list are worth noting because they indicate a care about correctness rather than just convenience. type-coverage runs at the end of the build and reports how much of the codebase is typed, and biome handles both linting and formatting in one tool rather than a linter plus a formatter.

The licence file is LICENSE.org, which is another detail that reinforces the format-first character of the project.

Where orga is the wrong tool

The first case is an editor. Orga is a parser with build integrations, and while the workspace contains @orgajs/react-editor and @orgajs/react-cm, a CodeMirror based editor for org content is a different product with a different maintenance burden. If your need is a good org-mode editing experience, an existing Emacs or third party editor covers it, and if your need is a browser-based org editor, the react-editor package is the thing to evaluate, not the parser.

The second case is content that is already in markdown. If your documents are markdown, remark and rehype already do everything orga does, and better, because they are the native path rather than a format that has to be translated into the same tree. Orga is for a specific situation, and that situation is org content.

The third case is anything requiring org-mode semantics rather than org syntax. The parser gives you a tree of what the document says. It does not give you the agenda, the capture templates, the refactoring, the TODO state machine, the publishing pipeline of a full org implementation, and the difference between a document that parses and a document that behaves the way Emacs behaves is large. If your requirement is that an org file work the way it works in Emacs, a parser is not enough.

The alternative worth comparing is converting at build time instead of parsing at runtime. A script that turns .org files into markdown, and then a standard remark pipeline, gives you the same web output with a conversion step and no org-specific plugins. The difference in approach is that orga keeps the org file as the source of truth inside a unified pipeline, so a remark plugin that inspects headings sees the same tree it would see in a markdown project, while a converter approach means the plugins only ever see markdown and the org-specific structure is flattened once and lost. For a documentation site where headings, lists and code blocks are all that matter, the converter is simpler. For a site where the org structure carries meaning, the parser is the only option that preserves it.

Editorial conclusion

orga suits a team that keeps its writing in org-mode and wants it to live in a JavaScript build pipeline, for example a documentation site or a content-driven frontend, because the unified AST means the standard remark and rehype plugins apply to org files the same way they apply to markdown. It is the wrong choice for an editor, since the project is a parser and a set of build integrations rather than an org-mode implementation, and for a team whose content is already in markdown. Before adopting it, check the package list in the workspace, since the core parser, the build tooling and the React editor live in separate packages, and read the examples directory before writing your own pipeline, because the getting-started example is where the unified integration is actually shown.

Frequently asked questions

What is orga and what does it parse?

Orga is a flexible org-mode syntax parser written in JavaScript. It parses org content into an AST, and the tree it produces is completely compatible with unified, so the standard remark and rehype plugins apply to org files.

Which packages does the orgajs workspace publish?

The workspace includes the core parser, the orga-build build tool, the oast-to-hast converter that turns an org AST into an HTML AST, the @orgajs/rollup plugin for Rollup and Vite, and the @orgajs/react-editor and @orgajs/react-cm React editor packages.

How do I import .org files in a Vite or Rollup project?

The @orgajs/rollup package is a plugin compatible with both Rollup and Vite that lets you import .org files directly in your project. For webpack there is a separate loader, @orgajs/loader.

Can I render React components inside an org file?

Yes. The README demonstrates rendering a React component directly in an org file using an export block containing JSX, and there is a live playground on the project site for trying it in the browser.

What licence is orga released under?

The project is MIT licensed, with the licence text in LICENSE.org at the repository root. The last push was on 2026-10-14, the same day as the orga 5.0.0, orga-build 0.11.0 and oast-to-hast 4.6.1 releases.

Official sources

  1. License: MIT
  2. orgapp/orgajs on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/orgapp-orgajs.svg)](https://hysenlabs.com/projects/orgapp-orgajs)

Was this useful?