Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Djot Laravel Package

php-collective/djot

PHP parser and renderer for Djot, the lightweight markup language created by CommonMark's author. Convert Djot markup to HTML through a clean, extensible API—a modern alternative to Markdown offering more consistent syntax, better footnotes, and richer built-in features.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Content authoring format for docs/CMS/knowledge base: Djot is a strictly-specified light markup language from John MacFarlane (Pandoc/CommonMark author). Adopting a parser is the enabling decision for "what do we let authors write in?" — this package makes that a buy rather than a build.
  • Build vs buy for a markup pipeline: Rolling your own parser is a multi-quarter trap (spec conformance, edge cases, XSS surface, round-tripping). An MIT-licensed parser collapses that to an integration task, leaving your team to own rendering, sanitization policy, and editor UX — the parts that are actually differentiating. As of 0.1.34 this now covers ingestion too, not just rendering (see next bullet).
  • Content migration and ingestion policy: The package now ships first-party importers in both directions of the legacy problem — MarkdownToDjot for existing Markdown corpora and an HTML importer for content currently stored as rendered markup. That changes the migration conversation from "we'd have to write a converter" to "we have a converter starting point and need a validation project." It also unlocks ingestion use cases: importing READMEs, past CMS bodies, HTML email, or legacy forum posts into a canonical Djot store.
  • Markdown extension sprawl: If your product has accreted footnotes, definition lists, attributes, tables, and math via a stack of Markdown plugins, Djot is a credible "one spec instead of ten extensions" consolidation play. This is a roadmap-level standardization decision, not a feature. 0.1.34 also strengthens the output side of the argument: Djot→Markdown emission now preserves emphasis/strong/deletion delimiter validity at punctuation and whitespace boundaries and keeps nested emphasis order, so Djot can be a superset authoring format that still exports clean Markdown to third parties.
  • Community/CMS interaction features (@mentions, #tags): MentionsExtension now accepts optional resolver and tagResolver closures plus a shared resolverContext, turning @name and #tag into host-app URLs. Architecturally this is the right shape — URL and permission logic stays in your app, the parser only identifies and substitutes. Tags are opt-in (Djot has no inline tag syntax), and refused mentions fall back to plain text across HTML, Markdown, and plain-text output. This supports a decision like "do we build notifications/mention-linking in-house or standardize on the parser's extension hook?" — but only if mention syntax is a settled product requirement, which it usually isn't at format-selection time.
  • Static site / docs-as-code and print pipelines: Djot's design target is complex documents and Pandoc compatibility, which supports decisions like "single source of truth rendered to HTML and PDF/DOCX" and "docs content lives in the repo."
  • Rich-text storage format: Choosing a canonical on-disk representation for user-generated or editorial content. A parser lets you store plain text and render at read time (auditable, diffable, portable) instead of storing opaque HTML/JSON blobs.
  • Author-facing diagnostics as a feature, not an afterthought: 0.1.34 makes inline warnings (undefined references, undefined footnotes, unattached attributes) report the authored line and column inside lists, quotes, tables, divs, and footnotes. That is a product decision enabler: broken references can be surfaced in the editor with a real location, and an "unattached attribute" typo can be a lint warning rather than silent data loss.
  • Use cases to prototype against: internal documentation portals, changelog/release-note rendering, CMS body fields, comment/forum formatting, README ingestion, email-to-HTML rendering, LLM-adjacent content normalization, and — new this release — one-time import of legacy Markdown/HTML content.
  • Explicit non-decision: this is still not a reason to migrate existing Markdown content wholesale. The importers make a spike cheap; they do not make migration free. Treat migration as a separate, costed project with a fidelity-diff harness on a representative corpus.

When to Consider This Package

Consider it when:

  • You are choosing a markup format now for greenfield content and want a spec with a real author behind it rather than a de-facto dialect.
  • Your content needs attributes, footnotes, definition lists, or precise inline semantics without bolting on Markdown extensions.
  • You need Pandoc-adjacent output paths (HTML plus print/ebook) and want one source format.
  • You need import paths — Markdown-in, HTML-in, Djot-out — to consolidate legacy content stores. MarkdownToDjot now preserves references, entities, pointy destinations and link titles, and keeps raw HTML inert by default (new MarkdownToDjot(trustedRawHtml: true) for trusted input). The HTML importer now keeps significant inline whitespace, treats blockquote inline runs as runs, renders nested quotation marks faithfully, and distinguishes authored ASCII punctuation from typographic punctuation. Still verify against your corpus; these are the exact class of bug that only shows up on real documents.
  • Your stack is PHP/Laravel and you want an in-process parser rather than shelling out to a Pandoc binary or a Node service — fewer moving parts, no sidecar runtime, no cross-language serialization.
  • You want mention/tag resolution for community or CMS content without building a second-pass text scanner. MentionsExtension resolvers keep host logic in the host app and default to safe plain-text on refusal.
  • Your team is comfortable treating a low-adoption dependency as vendorfable: MIT license means you can fork and maintain it if upstream stalls.

Look elsewhere when:

  • Ecosystem maturity is a hard requirement. Still ~25 stars, no meaningful dependent base, single-maintainer risk profile. 0.1.34 is a good release, but 0.x versioning means the "no breaking changes" guarantee is not semver-backed.
  • You need a single, canonical parser code path. 0.1.34's headline fix is that a fast HTML path and the authoritative parser disagreed on fenced code blocks with blank lines, and that the fast path now falls back when emphasis/strong seams could change the parse. Dual-path parsing is a legitimate performance strategy and a persistent correctness hazard. Unless you benchmark and validate, evaluate and ship on the authoritative path, and treat the fast path as an opt-in after load testing.
  • You need CommonMark/GFM exact compatibility — use league/commonmark, which has years of hardening, extension ecosystem, and security review behind it.
  • You need a WYSIWYG/editor story. This package is a parser/converter only; the editing experience (ProseMirror schema, toolbar, paste handling, collaborative editing) is entirely yours to build.
  • You need enterprise support, SLAs, or a security-response process. Still none; you own vulnerability triage. Note that the HTML and Markdown importers widen the input surface — imported content is untrusted input, and trustedRawHtml: true is an explicit footgun that must never be set on user-supplied data.
  • Throughput is a hard constraint. Still no published benchmarks. The existence of a fast path implies the maintainer is thinking about performance, but "there is an optimization" is not "there is a number." Load-test against your largest documents before committing, and know which path you're on.

Gating checks before adoption: run the full Djot spec test suite / conformance corpus yourself, and re-run it after every upgrade — much of this release is parity work against djot.js, which means parity is being established incrementally. Confirm the public API stability you need (AST access vs HTML-only output; whether warnings are machine-readable enough for editor integration). Verify PHP version support against your runtime. Check commit cadence over the last 6 months. Decide and document which parsing path production uses. Pin the version and record a fork-and-maintain contingency.

How to Pitch It (Stakeholders)

For executives (one paragraph): We have a recurring, low-differentiation cost: parsing and rendering the markup our authors and users write, plus the one-off cost of ever getting old content into a new format. Today that means either a pile of Markdown extensions or a homegrown parser we must maintain forever. This package is a small, MIT-licensed PHP parser for Djot — a newer light markup language from the author of Pandoc and CommonMark — that lets us standardize on one well-specified format, buy the parsing instead of building it, and now includes converters so the migration question has an answer that isn't "write your own." The upside is a smaller maintenance burden, a cleaner authoring model, a portable plain-text content format, and usable author-facing error locations. The honest risk is unchanged and mostly maturity: it is early-stage (pre-1.0) with a thin community, and this release shows us the parser still has two internal rendering paths that can disagree. So we would treat it as a contained, reversible bet — a spike behind an interface, no migration of existing content until a fidelity comparison passes, and a fork contingency because the license permits it. Cost to evaluate is days, not quarters.

For engineering (the ask):

  • Adopt behind an internal MarkupRenderer interface so the parser is swappable and never leaks into domain code. Same for import: wrap MarkdownToDjot and the HTML importer behind an Importer interface.
  • Timebox a spike: conformance corpus, our three gnarliest documents, an import dry-run of a real legacy corpus with a rendered-output diff, and a load test at p99 document size.
  • Pin the authoritative parse path in production. Treat the fast HTML path as an unvalidated optimization until benchmarked; a fast path that silently diverges from the reference parser is worse than a slow correct one. Add a regression test around fenced code blocks with blank lines and emphasis/strong delimiter seams — the exact class of bug 0.1.34 fixed.
  • Never construct MarkdownToDjot(trustedRawHtml: true) on user-supplied content, and keep raw HTML inert on import until the sanitization policy is written down.
  • If we use MentionsExtension, keep resolvers pure and dependency-free (they run inside parsing), and confirm the "refused mention renders as plain text" behavior matches the product requirement for private/deleted accounts.
  • We own sanitization and the editor; the package owns parsing, conversion, and author diagnostics.
  • Pin the version, watch upstream, re-run the conformance and import diff harness on every bump, and keep the fork path warm.
  • Success criteria: render correctness on our corpus, acceptable latency on a chosen path, import fidelity we can quantify, and zero bespoke parser code in our repo. If any gate fails, fall back to league/commonmark — no sunk cost.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings