npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@marlinjai/email-editor-core

v0.6.1

Published

Framework-agnostic engine of the email editor: document schema, block registry, MobX State Tree store, and the server-only MJML compiler

Readme

@marlinjai/email-editor-core

The framework-agnostic engine of @marlinjai/email-editor: the email document schema and its validation, migrateTemplate for stored documents, the block registry, the MobX State Tree store, and the MJML compiler.

Most apps install it for two things on their server: validating stored documents and compiling them to HTML.

import { migrateTemplate, isTemplateMigrationError } from '@marlinjai/email-editor-core';
import { createMJMLCompiler } from '@marlinjai/email-editor-core/server';

const doc = migrateTemplate(storedJson); // throws TemplateMigrationError with a typed `code`
const { html, mjml, errors } = await createMJMLCompiler().compile(doc); // asynchronous since mjml 5

Two entry points

| Import | Where | Contains | |--------|-------|----------| | @marlinjai/email-editor-core | browser and server | schema, types, validateTemplate, migrateTemplate, registry, store | | @marlinjai/email-editor-core/server | server only | MJML compiler and exporter, and importMjml (MJML source to a document), all depending on mjml, a Node.js-only package |

Never import /server from client code. In Next.js, list mjml, mjml-core, mjml-parser-xml, mjml-preset-core and mjml-validator in serverExternalPackages.

migrateTemplate(doc)

Returns the document at the current schema version (CURRENT_TEMPLATE_VERSION, today "1.1"; 1.1 added wrappers, a container around sections). For a 1.1 document it is the identity: the same object, validated. A 1.0 document comes back as a new object with only the version changed, except that a 1.0 section flagged isWrapper becomes a wrapper around that section. Otherwise it throws a TemplateMigrationError whose code is INVALID_INPUT, MISSING_VERSION, UNSUPPORTED_VERSION, NEWER_VERSION (written by a newer editor) or INVALID_DOCUMENT (with the schema issues). See the editor README for how to use it in an API route.

importMjml(source)

Reads an MJML document into the editor's document model and returns { document, warnings }; the document has passed migrateTemplate. An mj-wrapper becomes a wrapper holding its sections. What cannot become an editable block is kept as compiled HTML, so the mail does not change, and every such change is a warning with a path and the MJML it came from. Unreadable input throws an MjmlImportError with a code and, when it is one place, a line and column; mj-include is refused, never read from disk. See the editor README for what maps.

License

MIT