diff --git a/.changeset/hand-written-liquid-html-parser.md b/.changeset/hand-written-liquid-html-parser.md
new file mode 100644
index 000000000..0ee06def3
--- /dev/null
+++ b/.changeset/hand-written-liquid-html-parser.md
@@ -0,0 +1,16 @@
+---
+'@shopify/liquid-html-parser': minor
+'@shopify/theme-language-server-common': minor
+'@shopify/theme-check-common': minor
+'@shopify/prettier-plugin-liquid': minor
+'@shopify/theme-graph': minor
+---
+
+Adopt the hand-written `liquid-html-parser` for performance
+
+Replace the parser-combinator-based Liquid/HTML parser with a hand-written
+recursive-descent parser. The new parser is significantly faster, adds
+resilient parsing (it recovers from malformed input instead of bailing), and is
+adapted to the theme-tools source model. `theme-language-server-common`,
+`theme-check-common`, `prettier-plugin-liquid`, and `theme-graph` are updated to
+consume the new parser.
diff --git a/.changeset/port-theme-check-checks.md b/.changeset/port-theme-check-checks.md
new file mode 100644
index 000000000..105d752b5
--- /dev/null
+++ b/.changeset/port-theme-check-checks.md
@@ -0,0 +1,26 @@
+---
+'@shopify/theme-check-common': minor
+---
+
+Port additional theme-check checks
+
+Add the following checks:
+ - `LiquidComplexity` -- Reports Liquid files with high cyclomatic complexity (default threshold 120).
+ - `LiquidNestingDepth` -- Reports Liquid files with deeply nested control-flow structures (default max depth 10).
+ - `LiquidSyntaxError` -- Reports Liquid syntax errors.
+ - `MaxFileSize` -- Reports theme files that exceed Shopify's maximum per-file size.
+ - `ExcessiveSettingsCount` -- Reports section/block schemas declaring more top-level settings than the max (default 40).
+ - `BlockArgumentSettingCollision` -- Reports a plain block-tag argument whose name matches a setting id in the block's schema.
+ - `DuplicateBlockArguments` -- Reports duplicate argument names in a block tag.
+ - `MissingBlockArguments` -- Reports required `{% doc %}` arguments not provided on a block tag.
+ - `UnknownBlockSetting` -- Reports a `block.settings.` argument where `` is not in the block's schema.
+ - `UnrecognizedBlockArguments` -- Reports block-tag arguments not declared in the block's `{% doc %}` tag.
+ - `ValidBlockArgumentTypes` -- Reports type mismatches between block-tag arguments and their `{% doc %}` declarations.
+ - `SchemaOncePerFile` -- Reports when `{% schema %}` appears more than once in a file.
+ - `SchemaSectionOrBlockOnly` -- Reports `{% schema %}` used outside section or block files.
+ - `StylesheetOncePerFile` -- Reports when `{% stylesheet %}` appears more than once in a file.
+ - `StylesheetSectionOrBlockOnly` -- Reports `{% stylesheet %}` used outside section or block files.
+ - `JavascriptOncePerFile` -- Reports when `{% javascript %}` appears more than once in a file.
+ - `JavascriptSectionOrBlockOnly` -- Reports `{% javascript %}` used outside section or block files.
+
+`RequiredLayoutThemeObject` now flags any `layout/*.liquid` file missing the required theme objects, not just `layout/theme.liquid`.
diff --git a/packages/liquid-html-parser/.gitignore b/packages/liquid-html-parser/.gitignore
index 02a8b6d42..3a0374528 100644
--- a/packages/liquid-html-parser/.gitignore
+++ b/packages/liquid-html-parser/.gitignore
@@ -4,9 +4,12 @@ pnpm-debug.log*
.DS_Store
dawn
TODO
-grammar/liquid-html.ohm.js
-standalone.js
-standalone.js.LICENSE.txt
**/actual.liquid
coverage
.nyc_output
+
+# Generated parser fixtures (goldens + downloaded themes) — regenerated by scripts/setup-fixtures.ts
+fixtures/golden-html-ast/
+fixtures/golden-liquid-ast/
+fixtures/theme/
+fixtures/theme-bundle.ts
diff --git a/packages/liquid-html-parser/fixtures/error-corpus.ts b/packages/liquid-html-parser/fixtures/error-corpus.ts
new file mode 100644
index 000000000..db465c168
--- /dev/null
+++ b/packages/liquid-html-parser/fixtures/error-corpus.ts
@@ -0,0 +1,75 @@
+/*
+ * Adversarial error corpus for the tolerant-parser overhead benchmark.
+ *
+ * Every `source` here is *invalid* Liquid/HTML: the strict `toLiquidHtmlAST`
+ * throws on each one, so these sources exist only to exercise the tolerant
+ * path (`toTolerantLiquidHtmlAST`), which recovers instead of throwing and
+ * surfaces one `LiquidErrorNode` per region it gives up on.
+ *
+ * The bench arm that consumes this corpus measures resync/recovery cost, not
+ * throughput on clean input.
+ *
+ * Shape is identical to `THEME_FILES` in `theme-bundle.ts`
+ * (`Array<{ path; source }>`) so the bench loop stays uniform across corpora.
+ *
+ * Contract (verified in C2): each `source` passed to
+ * `toTolerantLiquidHtmlAST` returns a `DocumentNode` without throwing and
+ * contains at least one `LiquidErrorNode`.
+ */
+
+/*
+ * A single orphan close tag followed by a valid variable output. The close
+ * has no matching open, so the tolerant parser emits one error node, then
+ * resynchronizes on the next construct-open boundary and recovers the output.
+ *
+ * Repeating this unit forces the resync loop to fire once per unit — the
+ * "error every few tokens" density stress.
+ */
+const FREQUENT_ERROR_UNIT = "{% endfor %}{{ x }}{% endif %}{{ y }}";
+
+/*
+ * A well-formed Liquid+HTML fragment the strict parser accepts as-is.
+ *
+ * Repeated many times it builds a large clean body; a single orphan close
+ * tag appended near EOF then costs exactly one recovery, proving tail
+ * recovery does not rescan the whole document.
+ */
+const CLEAN_UNIT =
+ '