diff --git a/CHANGELOG.md b/CHANGELOG.md
index f558a3601ba80a485d79ae4db4abf7c3575db177..f3eec62dde62bec973838fb3d454be7da5b2547f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
 This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html),
 with the exception that 0.x versions can break between minor versions.
 
+## Unreleased
+### Changed
+- Modular JAR: Require at least Java 9 and add a module descriptor (module-info),
+  remove no longer necessary `Automatic-Module-Name` header
+- New package `org.commonmark.parser.beta` containing classes that are not part of
+  the stable API but are exported from the module (because they might be useful for
+  extension parsers).
+
 ## [0.21.0] - 2022-11-17
 ### Added
 - GitHub strikethrough: With the previous version we adjusted the
@@ -379,6 +387,7 @@ API breaking changes (caused by changes in spec):
 Initial release of commonmark-java, a port of commonmark.js with extensions
 for autolinking URLs, GitHub flavored strikethrough and tables.
 
+[0.22.0]: https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.21.0...commonmark-parent-0.22.0
 [0.21.0]: https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.20.0...commonmark-parent-0.21.0
 [0.20.0]: https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.19.0...commonmark-parent-0.20.0
 [0.19.0]: https://github.com/commonmark/commonmark-java/compare/commonmark-parent-0.18.2...commonmark-parent-0.19.0
diff --git a/README.md b/README.md
index da7a07dd22df550d0192e29875f60271f96a41c3..4182ee2407f65403074abd500ce73e05a7f4cffa 100644
--- a/README.md
+++ b/README.md
@@ -44,7 +44,8 @@ The module names to use in Java 9 are `org.commonmark`,
 
 Note that for 0.x releases of this library, the API is not considered stable
 yet and may break between minor releases. After 1.0, [Semantic Versioning] will
-be followed.
+be followed. A package containing `beta` means it's not subject to stable API
+guarantees yet; but for normal usage it should not be necessary to use.
 
 See the [spec.txt](commonmark-test-util/src/main/resources/spec.txt)
 file if you're wondering which version of the spec is currently
@@ -399,7 +400,7 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) file.
 License
 -------
 
-Copyright (c) 2015-2019 Atlassian and others.
+Copyright (c) Atlassian and others.
 
 BSD (2-clause) licensed, see LICENSE.txt file.
 
diff --git a/commonmark-ext-autolink/pom.xml b/commonmark-ext-autolink/pom.xml
index c82ecdae8df285c39710fd05b98b6404657ac816..2f70f7a0e4621b6148644f6293ff4ee05ef99b0c 100644
--- a/commonmark-ext-autolink/pom.xml
+++ b/commonmark-ext-autolink/pom.xml
@@ -12,7 +12,7 @@
     <description>commonmark-java extension for turning plain URLs and email addresses into links</description>
 
     <properties>
-        <autolink.version>0.10.0</autolink.version>
+        <autolink.version>0.11.0</autolink.version>
     </properties>
 
     <dependencies>
@@ -33,20 +33,4 @@
         </dependency>
     </dependencies>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifestEntries>
-                            <Automatic-Module-Name>org.commonmark.ext.autolink</Automatic-Module-Name>
-                        </manifestEntries>
-                    </archive>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
 </project>
diff --git a/commonmark-ext-autolink/src/main/java/module-info.java b/commonmark-ext-autolink/src/main/java/module-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..264d02aea1878e0e4cc03975b8a67269ca84488d
--- /dev/null
+++ b/commonmark-ext-autolink/src/main/java/module-info.java
@@ -0,0 +1,4 @@
+module org.commonmark.ext.autolink {
+    requires org.commonmark;
+    requires org.nibor.autolink;
+}
diff --git a/commonmark-ext-gfm-strikethrough/pom.xml b/commonmark-ext-gfm-strikethrough/pom.xml
index 878a1e5863c480a9de55b908bb2eb4ff96f5804c..b452073ab47b50f489a224092f097cb3141e7f20 100644
--- a/commonmark-ext-gfm-strikethrough/pom.xml
+++ b/commonmark-ext-gfm-strikethrough/pom.xml
@@ -24,20 +24,4 @@
         </dependency>
     </dependencies>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifestEntries>
-                            <Automatic-Module-Name>org.commonmark.ext.gfm.strikethrough</Automatic-Module-Name>
-                        </manifestEntries>
-                    </archive>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
 </project>
diff --git a/commonmark-ext-gfm-strikethrough/src/main/java/module-info.java b/commonmark-ext-gfm-strikethrough/src/main/java/module-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..cebaa098ea29e3c5b30f972478ed81d25084e3b6
--- /dev/null
+++ b/commonmark-ext-gfm-strikethrough/src/main/java/module-info.java
@@ -0,0 +1,3 @@
+module org.commonmark.ext.gfm.strikethrough {
+    requires org.commonmark;
+}
diff --git a/commonmark-ext-gfm-tables/pom.xml b/commonmark-ext-gfm-tables/pom.xml
index c6448889f0ec0dfeaad9679530b99e5ef35c78fc..01fe2b23c1168718215c1df6ab42efe870b69cdd 100644
--- a/commonmark-ext-gfm-tables/pom.xml
+++ b/commonmark-ext-gfm-tables/pom.xml
@@ -24,20 +24,4 @@
         </dependency>
     </dependencies>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifestEntries>
-                            <Automatic-Module-Name>org.commonmark.ext.gfm.tables</Automatic-Module-Name>
-                        </manifestEntries>
-                    </archive>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
 </project>
diff --git a/commonmark-ext-gfm-tables/src/main/java/module-info.java b/commonmark-ext-gfm-tables/src/main/java/module-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..da1dac5ed5ce5f27e333e14c0a951d1b94179cec
--- /dev/null
+++ b/commonmark-ext-gfm-tables/src/main/java/module-info.java
@@ -0,0 +1,3 @@
+module org.commonmark.ext.gfm.tables {
+    requires org.commonmark;
+}
diff --git a/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/internal/TableBlockParser.java b/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/internal/TableBlockParser.java
index b7cea14dbc12eac8e44abb70800e7a500164ecfb..14e461dba39ce006c474c0705f7d1c52a8648927 100644
--- a/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/internal/TableBlockParser.java
+++ b/commonmark-ext-gfm-tables/src/main/java/org/commonmark/ext/gfm/tables/internal/TableBlockParser.java
@@ -1,13 +1,13 @@
 package org.commonmark.ext.gfm.tables.internal;
 
 import org.commonmark.ext.gfm.tables.*;
-import org.commonmark.internal.util.Parsing;
 import org.commonmark.node.Block;
 import org.commonmark.node.Node;
 import org.commonmark.node.SourceSpan;
 import org.commonmark.parser.InlineParser;
 import org.commonmark.parser.SourceLine;
 import org.commonmark.parser.SourceLines;
+import org.commonmark.parser.beta.Parsing;
 import org.commonmark.parser.block.*;
 
 import java.util.ArrayList;
diff --git a/commonmark-ext-heading-anchor/pom.xml b/commonmark-ext-heading-anchor/pom.xml
index 49bc4a03236cbdfeb0dc4d9c79df0c447f71cf15..330490ea6117ba2677c93bb194e097d40dd8ed53 100644
--- a/commonmark-ext-heading-anchor/pom.xml
+++ b/commonmark-ext-heading-anchor/pom.xml
@@ -24,20 +24,4 @@
         </dependency>
     </dependencies>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifestEntries>
-                            <Automatic-Module-Name>org.commonmark.ext.heading.anchor</Automatic-Module-Name>
-                        </manifestEntries>
-                    </archive>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
 </project>
diff --git a/commonmark-ext-heading-anchor/src/main/java/module-info.java b/commonmark-ext-heading-anchor/src/main/java/module-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..8b6c7b6b3b0569020295a314ab786496f4d2c283
--- /dev/null
+++ b/commonmark-ext-heading-anchor/src/main/java/module-info.java
@@ -0,0 +1,3 @@
+module org.commonmark.ext.heading.anchor {
+    requires org.commonmark;
+}
diff --git a/commonmark-ext-image-attributes/pom.xml b/commonmark-ext-image-attributes/pom.xml
index 959b1406c0950ce21a7ca811232fdb44ab05c2c8..6fbec9007bfc8b9d7777f889403794e81f21689b 100644
--- a/commonmark-ext-image-attributes/pom.xml
+++ b/commonmark-ext-image-attributes/pom.xml
@@ -24,20 +24,4 @@
         </dependency>
     </dependencies>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifestEntries>
-                            <Automatic-Module-Name>org.commonmark.ext.image.attributes</Automatic-Module-Name>
-                        </manifestEntries>
-                    </archive>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
 </project>
diff --git a/commonmark-ext-image-attributes/src/main/java/module-info.java b/commonmark-ext-image-attributes/src/main/java/module-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..2af5cac99a94d4b4de1f6e29bacf99126e75976c
--- /dev/null
+++ b/commonmark-ext-image-attributes/src/main/java/module-info.java
@@ -0,0 +1,3 @@
+module org.commonmark.ext.image.attributes {
+    requires org.commonmark;
+}
diff --git a/commonmark-ext-ins/pom.xml b/commonmark-ext-ins/pom.xml
index 708532472fc3e76383a5373b6ef8340b66491e1f..68e5f627b5a6139d8edeca0159eddf7491b09b86 100644
--- a/commonmark-ext-ins/pom.xml
+++ b/commonmark-ext-ins/pom.xml
@@ -24,20 +24,4 @@
         </dependency>
     </dependencies>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifestEntries>
-                            <Automatic-Module-Name>org.commonmark.ext.ins</Automatic-Module-Name>
-                        </manifestEntries>
-                    </archive>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
 </project>
diff --git a/commonmark-ext-ins/src/main/java/module-info.java b/commonmark-ext-ins/src/main/java/module-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..3527f12d342283880177187dfe4181316a0e1a55
--- /dev/null
+++ b/commonmark-ext-ins/src/main/java/module-info.java
@@ -0,0 +1,3 @@
+module org.commonmark.ext.ins {
+    requires org.commonmark;
+}
diff --git a/commonmark-ext-task-list-items/pom.xml b/commonmark-ext-task-list-items/pom.xml
index ec3ac1a1f46aa6295bff5e9e8ef9510686e2e803..3e3bebf3257144140f795d35aba89ac2dd48d8ee 100644
--- a/commonmark-ext-task-list-items/pom.xml
+++ b/commonmark-ext-task-list-items/pom.xml
@@ -24,20 +24,4 @@
         </dependency>
     </dependencies>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifestEntries>
-                            <Automatic-Module-Name>org.commonmark.ext.task.list.items</Automatic-Module-Name>
-                        </manifestEntries>
-                    </archive>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
 </project>
diff --git a/commonmark-ext-task-list-items/src/main/java/module-info.java b/commonmark-ext-task-list-items/src/main/java/module-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..3acc7ba9184b533ddc207d405563fc703bee60cf
--- /dev/null
+++ b/commonmark-ext-task-list-items/src/main/java/module-info.java
@@ -0,0 +1,3 @@
+module org.commonmark.ext.task.list.items {
+    requires org.commonmark;
+}
diff --git a/commonmark-ext-yaml-front-matter/pom.xml b/commonmark-ext-yaml-front-matter/pom.xml
index e5e120caa04166ef1c564afcd4a36a83a99bb70a..97bdc5c4875f438f39b546ef382b3253a5baa008 100644
--- a/commonmark-ext-yaml-front-matter/pom.xml
+++ b/commonmark-ext-yaml-front-matter/pom.xml
@@ -24,20 +24,4 @@
         </dependency>
     </dependencies>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifestEntries>
-                            <Automatic-Module-Name>org.commonmark.ext.front.matter</Automatic-Module-Name>
-                        </manifestEntries>
-                    </archive>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
 </project>
diff --git a/commonmark-ext-yaml-front-matter/src/main/java/module-info.java b/commonmark-ext-yaml-front-matter/src/main/java/module-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..159cae2a4a1fd235218363782f9314aa0803e7d4
--- /dev/null
+++ b/commonmark-ext-yaml-front-matter/src/main/java/module-info.java
@@ -0,0 +1,3 @@
+module org.commonmark.ext.front.matter {
+    requires org.commonmark;
+}
diff --git a/commonmark-ext-yaml-front-matter/src/main/java/org/commonmark/ext/front/matter/internal/YamlFrontMatterBlockParser.java b/commonmark-ext-yaml-front-matter/src/main/java/org/commonmark/ext/front/matter/internal/YamlFrontMatterBlockParser.java
index 2010b4f71d9d4a6a72e1f4f5752700b321eacd62..469cf4e2fecc905266297c1987186feafa15adfa 100644
--- a/commonmark-ext-yaml-front-matter/src/main/java/org/commonmark/ext/front/matter/internal/YamlFrontMatterBlockParser.java
+++ b/commonmark-ext-yaml-front-matter/src/main/java/org/commonmark/ext/front/matter/internal/YamlFrontMatterBlockParser.java
@@ -2,8 +2,8 @@ package org.commonmark.ext.front.matter.internal;
 
 import org.commonmark.ext.front.matter.YamlFrontMatterBlock;
 import org.commonmark.ext.front.matter.YamlFrontMatterNode;
-import org.commonmark.internal.DocumentBlockParser;
 import org.commonmark.node.Block;
+import org.commonmark.node.Document;
 import org.commonmark.parser.InlineParser;
 import org.commonmark.parser.SourceLine;
 import org.commonmark.parser.block.*;
@@ -119,7 +119,7 @@ public class YamlFrontMatterBlockParser extends AbstractBlockParser {
             CharSequence line = state.getLine().getContent();
             BlockParser parentParser = matchedBlockParser.getMatchedBlockParser();
             // check whether this line is the first line of whole document or not
-            if (parentParser instanceof DocumentBlockParser && parentParser.getBlock().getFirstChild() == null &&
+            if (parentParser.getBlock() instanceof Document && parentParser.getBlock().getFirstChild() == null &&
                     REGEX_BEGIN.matcher(line).matches()) {
                 return BlockStart.of(new YamlFrontMatterBlockParser()).atIndex(state.getNextNonSpaceIndex());
             }
diff --git a/commonmark-test-util/pom.xml b/commonmark-test-util/pom.xml
index c61000412636c5172c1c1741d853a43980e3a66e..ce332e6c298e6fa8faa9e2d0ee3a2cd41057cfc9 100644
--- a/commonmark-test-util/pom.xml
+++ b/commonmark-test-util/pom.xml
@@ -18,20 +18,4 @@
         </dependency>
     </dependencies>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifestEntries>
-                            <Automatic-Module-Name>org.commonmark.testutil</Automatic-Module-Name>
-                        </manifestEntries>
-                    </archive>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
 </project>
diff --git a/commonmark-test-util/src/main/java/module-info.java b/commonmark-test-util/src/main/java/module-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..dba6945cd248f73ff0f0d09c8710559263f96c73
--- /dev/null
+++ b/commonmark-test-util/src/main/java/module-info.java
@@ -0,0 +1,3 @@
+module org.commonmark.testutil {
+    requires junit;
+}
diff --git a/commonmark/pom.xml b/commonmark/pom.xml
index 9988370a8b0e214ed539486efc5accf37cc4edd1..524ba9c4235268e5efff1493ef29de53af747147 100644
--- a/commonmark/pom.xml
+++ b/commonmark/pom.xml
@@ -29,22 +29,6 @@
         </dependency>
     </dependencies>
 
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-jar-plugin</artifactId>
-                <configuration>
-                    <archive>
-                        <manifestEntries>
-                            <Automatic-Module-Name>org.commonmark</Automatic-Module-Name>
-                        </manifestEntries>
-                    </archive>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
     <profiles>
         <profile>
             <id>benchmark</id>
diff --git a/commonmark/src/main/java/module-info.java b/commonmark/src/main/java/module-info.java
new file mode 100644
index 0000000000000000000000000000000000000000..4101708c8bfa10510bc97cca49b6f0610aee811f
--- /dev/null
+++ b/commonmark/src/main/java/module-info.java
@@ -0,0 +1,11 @@
+module org.commonmark {
+    exports org.commonmark;
+    exports org.commonmark.node;
+    exports org.commonmark.parser;
+    exports org.commonmark.parser.beta;
+    exports org.commonmark.parser.block;
+    exports org.commonmark.parser.delimiter;
+    exports org.commonmark.renderer;
+    exports org.commonmark.renderer.html;
+    exports org.commonmark.renderer.text;
+}
diff --git a/commonmark/src/main/java/org/commonmark/internal/BlockQuoteParser.java b/commonmark/src/main/java/org/commonmark/internal/BlockQuoteParser.java
index 00cdbc11e4ab6d4e5694d4e22c08c1b790318cf4..8dd56a20122f77fd5a8de356ab938e99ecd26b67 100644
--- a/commonmark/src/main/java/org/commonmark/internal/BlockQuoteParser.java
+++ b/commonmark/src/main/java/org/commonmark/internal/BlockQuoteParser.java
@@ -1,8 +1,8 @@
 package org.commonmark.internal;
 
-import org.commonmark.internal.util.Parsing;
 import org.commonmark.node.Block;
 import org.commonmark.node.BlockQuote;
+import org.commonmark.parser.beta.Parsing;
 import org.commonmark.parser.block.*;
 
 public class BlockQuoteParser extends AbstractBlockParser {
diff --git a/commonmark/src/main/java/org/commonmark/internal/Bracket.java b/commonmark/src/main/java/org/commonmark/internal/Bracket.java
index 46296262f486b6ae785db8f32fcb86e7548955d1..9c73a13272ec9b4c70a0d4ffc0db86f14bd860e5 100644
--- a/commonmark/src/main/java/org/commonmark/internal/Bracket.java
+++ b/commonmark/src/main/java/org/commonmark/internal/Bracket.java
@@ -1,7 +1,7 @@
 package org.commonmark.internal;
 
-import org.commonmark.internal.inline.Position;
 import org.commonmark.node.Text;
+import org.commonmark.parser.beta.Position;
 
 /**
  * Opening bracket for links (<code>[</code>) or images (<code>![</code>).
diff --git a/commonmark/src/main/java/org/commonmark/internal/DocumentParser.java b/commonmark/src/main/java/org/commonmark/internal/DocumentParser.java
index 086c3dbc06dd03542577a759e191abc217f00747..cb5aa4b42565a6fc7f1ce92d0ab465ad135e04c5 100644
--- a/commonmark/src/main/java/org/commonmark/internal/DocumentParser.java
+++ b/commonmark/src/main/java/org/commonmark/internal/DocumentParser.java
@@ -1,8 +1,8 @@
 package org.commonmark.internal;
 
-import org.commonmark.internal.util.Parsing;
 import org.commonmark.node.*;
 import org.commonmark.parser.*;
+import org.commonmark.parser.beta.Parsing;
 import org.commonmark.parser.block.*;
 import org.commonmark.parser.delimiter.DelimiterProcessor;
 
diff --git a/commonmark/src/main/java/org/commonmark/internal/FencedCodeBlockParser.java b/commonmark/src/main/java/org/commonmark/internal/FencedCodeBlockParser.java
index 2d7d2c0c96372d7e6ef1df43280422afd9a5e274..8a56198fd49313fbaf51883fa998fac34d15e2ac 100644
--- a/commonmark/src/main/java/org/commonmark/internal/FencedCodeBlockParser.java
+++ b/commonmark/src/main/java/org/commonmark/internal/FencedCodeBlockParser.java
@@ -1,9 +1,9 @@
 package org.commonmark.internal;
 
-import org.commonmark.internal.util.Parsing;
 import org.commonmark.node.Block;
 import org.commonmark.node.FencedCodeBlock;
 import org.commonmark.parser.SourceLine;
+import org.commonmark.parser.beta.Parsing;
 import org.commonmark.parser.block.*;
 
 import static org.commonmark.internal.util.Escaping.unescapeString;
diff --git a/commonmark/src/main/java/org/commonmark/internal/HeadingParser.java b/commonmark/src/main/java/org/commonmark/internal/HeadingParser.java
index 81c60d0d1562d3aefca57145934ed40db69da585..f6b93703217300b999997211cf90f47093923174 100644
--- a/commonmark/src/main/java/org/commonmark/internal/HeadingParser.java
+++ b/commonmark/src/main/java/org/commonmark/internal/HeadingParser.java
@@ -1,13 +1,13 @@
 package org.commonmark.internal;
 
-import org.commonmark.internal.inline.Position;
-import org.commonmark.internal.inline.Scanner;
-import org.commonmark.internal.util.Parsing;
 import org.commonmark.node.Block;
 import org.commonmark.node.Heading;
 import org.commonmark.parser.InlineParser;
 import org.commonmark.parser.SourceLine;
 import org.commonmark.parser.SourceLines;
+import org.commonmark.parser.beta.Parsing;
+import org.commonmark.parser.beta.Position;
+import org.commonmark.parser.beta.Scanner;
 import org.commonmark.parser.block.*;
 
 public class HeadingParser extends AbstractBlockParser {
diff --git a/commonmark/src/main/java/org/commonmark/internal/HtmlBlockParser.java b/commonmark/src/main/java/org/commonmark/internal/HtmlBlockParser.java
index 0e2050567b9fda2e52715919a2578e87ab4d4572..8ee233f7d79492a44269206e0e901dc67ffd3c2b 100644
--- a/commonmark/src/main/java/org/commonmark/internal/HtmlBlockParser.java
+++ b/commonmark/src/main/java/org/commonmark/internal/HtmlBlockParser.java
@@ -1,10 +1,10 @@
 package org.commonmark.internal;
 
-import org.commonmark.internal.util.Parsing;
 import org.commonmark.node.Block;
 import org.commonmark.node.HtmlBlock;
 import org.commonmark.node.Paragraph;
 import org.commonmark.parser.SourceLine;
+import org.commonmark.parser.beta.Parsing;
 import org.commonmark.parser.block.*;
 
 import java.util.regex.Pattern;
diff --git a/commonmark/src/main/java/org/commonmark/internal/IndentedCodeBlockParser.java b/commonmark/src/main/java/org/commonmark/internal/IndentedCodeBlockParser.java
index af74a587cc88662a86823e588d02cf39c4b778a9..521963f5c1deaecf096289c6279339b1614948bc 100644
--- a/commonmark/src/main/java/org/commonmark/internal/IndentedCodeBlockParser.java
+++ b/commonmark/src/main/java/org/commonmark/internal/IndentedCodeBlockParser.java
@@ -1,10 +1,10 @@
 package org.commonmark.internal;
 
-import org.commonmark.internal.util.Parsing;
 import org.commonmark.node.Block;
 import org.commonmark.node.IndentedCodeBlock;
 import org.commonmark.node.Paragraph;
 import org.commonmark.parser.SourceLine;
+import org.commonmark.parser.beta.Parsing;
 import org.commonmark.parser.block.*;
 
 import java.util.ArrayList;
diff --git a/commonmark/src/main/java/org/commonmark/internal/InlineParserImpl.java b/commonmark/src/main/java/org/commonmark/internal/InlineParserImpl.java
index c14b9e88579d49cfd2a61a6186bd5d47695abf9e..84bf55accd16da12e36f50c3b458c53a060a099e 100644
--- a/commonmark/src/main/java/org/commonmark/internal/InlineParserImpl.java
+++ b/commonmark/src/main/java/org/commonmark/internal/InlineParserImpl.java
@@ -1,14 +1,15 @@
 package org.commonmark.internal;
 
-import org.commonmark.internal.inline.Scanner;
 import org.commonmark.internal.inline.*;
 import org.commonmark.internal.util.Escaping;
 import org.commonmark.internal.util.LinkScanner;
-import org.commonmark.internal.util.Parsing;
 import org.commonmark.node.*;
 import org.commonmark.parser.InlineParser;
 import org.commonmark.parser.InlineParserContext;
 import org.commonmark.parser.SourceLines;
+import org.commonmark.parser.beta.Parsing;
+import org.commonmark.parser.beta.Position;
+import org.commonmark.parser.beta.Scanner;
 import org.commonmark.parser.delimiter.DelimiterProcessor;
 
 import java.util.*;
diff --git a/commonmark/src/main/java/org/commonmark/internal/LinkReferenceDefinitionParser.java b/commonmark/src/main/java/org/commonmark/internal/LinkReferenceDefinitionParser.java
index 2bceb75494ae0f19786868fb390f4db09bef94ee..d11a6f228173599cf0d0600c0396663344f8f5ab 100644
--- a/commonmark/src/main/java/org/commonmark/internal/LinkReferenceDefinitionParser.java
+++ b/commonmark/src/main/java/org/commonmark/internal/LinkReferenceDefinitionParser.java
@@ -1,13 +1,13 @@
 package org.commonmark.internal;
 
-import org.commonmark.internal.inline.Position;
-import org.commonmark.internal.inline.Scanner;
 import org.commonmark.internal.util.Escaping;
 import org.commonmark.internal.util.LinkScanner;
 import org.commonmark.node.LinkReferenceDefinition;
 import org.commonmark.node.SourceSpan;
 import org.commonmark.parser.SourceLine;
 import org.commonmark.parser.SourceLines;
+import org.commonmark.parser.beta.Position;
+import org.commonmark.parser.beta.Scanner;
 
 import java.util.ArrayList;
 import java.util.List;
diff --git a/commonmark/src/main/java/org/commonmark/internal/ListBlockParser.java b/commonmark/src/main/java/org/commonmark/internal/ListBlockParser.java
index 0ff644a47120962a81ad2800e02c07dfb86b1db8..05608c3597e8fb2c142ca34f25b122d51ee2d9d6 100644
--- a/commonmark/src/main/java/org/commonmark/internal/ListBlockParser.java
+++ b/commonmark/src/main/java/org/commonmark/internal/ListBlockParser.java
@@ -1,7 +1,7 @@
 package org.commonmark.internal;
 
-import org.commonmark.internal.util.Parsing;
 import org.commonmark.node.*;
+import org.commonmark.parser.beta.Parsing;
 import org.commonmark.parser.block.*;
 
 public class ListBlockParser extends AbstractBlockParser {
diff --git a/commonmark/src/main/java/org/commonmark/internal/inline/AutolinkInlineParser.java b/commonmark/src/main/java/org/commonmark/internal/inline/AutolinkInlineParser.java
index ecfd2d9725e0d24ec444ef0bdd793841074d454e..36c43e196287c7cb1ed72dc846899ebdc2c00e5f 100644
--- a/commonmark/src/main/java/org/commonmark/internal/inline/AutolinkInlineParser.java
+++ b/commonmark/src/main/java/org/commonmark/internal/inline/AutolinkInlineParser.java
@@ -3,6 +3,8 @@ package org.commonmark.internal.inline;
 import org.commonmark.node.Link;
 import org.commonmark.node.Text;
 import org.commonmark.parser.SourceLines;
+import org.commonmark.parser.beta.Position;
+import org.commonmark.parser.beta.Scanner;
 
 import java.util.regex.Pattern;
 
diff --git a/commonmark/src/main/java/org/commonmark/internal/inline/BackslashInlineParser.java b/commonmark/src/main/java/org/commonmark/internal/inline/BackslashInlineParser.java
index f57a67a741c1b980ce85338d3bf8521840cfb82d..02c136951bdd0ccabdc2f311e5f08d4af34b7afa 100644
--- a/commonmark/src/main/java/org/commonmark/internal/inline/BackslashInlineParser.java
+++ b/commonmark/src/main/java/org/commonmark/internal/inline/BackslashInlineParser.java
@@ -2,8 +2,8 @@ package org.commonmark.internal.inline;
 
 import org.commonmark.internal.util.Escaping;
 import org.commonmark.node.HardLineBreak;
-import org.commonmark.node.Node;
 import org.commonmark.node.Text;
+import org.commonmark.parser.beta.Scanner;
 
 import java.util.regex.Pattern;
 
diff --git a/commonmark/src/main/java/org/commonmark/internal/inline/BackticksInlineParser.java b/commonmark/src/main/java/org/commonmark/internal/inline/BackticksInlineParser.java
index ad079444a10ab2f6e1f21899034089b0861bffce..d949fff572ccf1eeff909e96947461d62ff6f2eb 100644
--- a/commonmark/src/main/java/org/commonmark/internal/inline/BackticksInlineParser.java
+++ b/commonmark/src/main/java/org/commonmark/internal/inline/BackticksInlineParser.java
@@ -1,9 +1,11 @@
 package org.commonmark.internal.inline;
 
-import org.commonmark.internal.util.Parsing;
 import org.commonmark.node.Code;
 import org.commonmark.node.Text;
 import org.commonmark.parser.SourceLines;
+import org.commonmark.parser.beta.Parsing;
+import org.commonmark.parser.beta.Position;
+import org.commonmark.parser.beta.Scanner;
 
 /**
  * Attempt to parse backticks, returning either a backtick code span or a literal sequence of backticks.
diff --git a/commonmark/src/main/java/org/commonmark/internal/inline/EntityInlineParser.java b/commonmark/src/main/java/org/commonmark/internal/inline/EntityInlineParser.java
index c29b8694f87cc7b126024ca84c3db1d89b186f4d..90aff896f05214ad86c45a4e8310e3f66bdcd081 100644
--- a/commonmark/src/main/java/org/commonmark/internal/inline/EntityInlineParser.java
+++ b/commonmark/src/main/java/org/commonmark/internal/inline/EntityInlineParser.java
@@ -3,6 +3,8 @@ package org.commonmark.internal.inline;
 import org.commonmark.internal.util.AsciiMatcher;
 import org.commonmark.internal.util.Html5Entities;
 import org.commonmark.node.Text;
+import org.commonmark.parser.beta.Position;
+import org.commonmark.parser.beta.Scanner;
 
 /**
  * Attempts to parse a HTML entity or numeric character reference.
diff --git a/commonmark/src/main/java/org/commonmark/internal/inline/HtmlInlineParser.java b/commonmark/src/main/java/org/commonmark/internal/inline/HtmlInlineParser.java
index 605901c22f3edfa1223ef0d817550149e67e3c71..f0e7f8487d69b28e71119d4f0c9cf2a35e86e228 100644
--- a/commonmark/src/main/java/org/commonmark/internal/inline/HtmlInlineParser.java
+++ b/commonmark/src/main/java/org/commonmark/internal/inline/HtmlInlineParser.java
@@ -2,6 +2,8 @@ package org.commonmark.internal.inline;
 
 import org.commonmark.internal.util.AsciiMatcher;
 import org.commonmark.node.HtmlInline;
+import org.commonmark.parser.beta.Position;
+import org.commonmark.parser.beta.Scanner;
 
 /**
  * Attempt to parse inline HTML.
diff --git a/commonmark/src/main/java/org/commonmark/internal/inline/InlineParserState.java b/commonmark/src/main/java/org/commonmark/internal/inline/InlineParserState.java
index f6cb6bf4929a40f321685cebbaa98ce73fc841ad..ea8689be53e9dd2ff862b0640e8482e172e6883f 100644
--- a/commonmark/src/main/java/org/commonmark/internal/inline/InlineParserState.java
+++ b/commonmark/src/main/java/org/commonmark/internal/inline/InlineParserState.java
@@ -1,5 +1,8 @@
 package org.commonmark.internal.inline;
 
+import org.commonmark.parser.beta.Position;
+import org.commonmark.parser.beta.Scanner;
+
 public interface InlineParserState {
 
     /**
diff --git a/commonmark/src/main/java/org/commonmark/internal/inline/ParsedInline.java b/commonmark/src/main/java/org/commonmark/internal/inline/ParsedInline.java
index 7e6ece88e37c3994b45b816472ebd40975d14da3..7223c1687c080b6720a0f5ba75cbf24ea7c2f327 100644
--- a/commonmark/src/main/java/org/commonmark/internal/inline/ParsedInline.java
+++ b/commonmark/src/main/java/org/commonmark/internal/inline/ParsedInline.java
@@ -1,6 +1,7 @@
 package org.commonmark.internal.inline;
 
 import org.commonmark.node.Node;
+import org.commonmark.parser.beta.Position;
 
 public abstract class ParsedInline {
 
diff --git a/commonmark/src/main/java/org/commonmark/internal/inline/ParsedInlineImpl.java b/commonmark/src/main/java/org/commonmark/internal/inline/ParsedInlineImpl.java
index aea325f27bba1fda55d9187ef533b92a3c353214..55f9cc4da00fb879734a481f37a744ad88c47b8c 100644
--- a/commonmark/src/main/java/org/commonmark/internal/inline/ParsedInlineImpl.java
+++ b/commonmark/src/main/java/org/commonmark/internal/inline/ParsedInlineImpl.java
@@ -1,6 +1,7 @@
 package org.commonmark.internal.inline;
 
 import org.commonmark.node.Node;
+import org.commonmark.parser.beta.Position;
 
 public class ParsedInlineImpl extends ParsedInline {
     private final Node node;
diff --git a/commonmark/src/main/java/org/commonmark/internal/util/LinkScanner.java b/commonmark/src/main/java/org/commonmark/internal/util/LinkScanner.java
index 3ca34c5f0a7dd122f4bb8ebcc817edf6fbe70dbb..641572de55639d2a81659fdab99fb871e0881201 100644
--- a/commonmark/src/main/java/org/commonmark/internal/util/LinkScanner.java
+++ b/commonmark/src/main/java/org/commonmark/internal/util/LinkScanner.java
@@ -1,6 +1,7 @@
 package org.commonmark.internal.util;
 
-import org.commonmark.internal.inline.Scanner;
+import org.commonmark.parser.beta.Parsing;
+import org.commonmark.parser.beta.Scanner;
 
 public class LinkScanner {
 
diff --git a/commonmark/src/main/java/org/commonmark/internal/util/Parsing.java b/commonmark/src/main/java/org/commonmark/parser/beta/Parsing.java
similarity index 99%
rename from commonmark/src/main/java/org/commonmark/internal/util/Parsing.java
rename to commonmark/src/main/java/org/commonmark/parser/beta/Parsing.java
index 8b02e99b10ebb13ba592bd01cfd5af12c6ab173f..68aa0c3cced2e4d2592233087bc4ac748249adbc 100644
--- a/commonmark/src/main/java/org/commonmark/internal/util/Parsing.java
+++ b/commonmark/src/main/java/org/commonmark/parser/beta/Parsing.java
@@ -1,4 +1,4 @@
-package org.commonmark.internal.util;
+package org.commonmark.parser.beta;
 
 public class Parsing {
 
diff --git a/commonmark/src/main/java/org/commonmark/internal/inline/Position.java b/commonmark/src/main/java/org/commonmark/parser/beta/Position.java
similarity index 89%
rename from commonmark/src/main/java/org/commonmark/internal/inline/Position.java
rename to commonmark/src/main/java/org/commonmark/parser/beta/Position.java
index 5f06a063a31541705f3bc9f826cc949d6e006022..3dbb4870fe3450193469b7837ca17d7c75161a3c 100644
--- a/commonmark/src/main/java/org/commonmark/internal/inline/Position.java
+++ b/commonmark/src/main/java/org/commonmark/parser/beta/Position.java
@@ -1,4 +1,4 @@
-package org.commonmark.internal.inline;
+package org.commonmark.parser.beta;
 
 /**
  * Position within a {@link Scanner}. This is intentionally kept opaque so as not to expose the internal structure of
diff --git a/commonmark/src/main/java/org/commonmark/internal/inline/Scanner.java b/commonmark/src/main/java/org/commonmark/parser/beta/Scanner.java
similarity index 99%
rename from commonmark/src/main/java/org/commonmark/internal/inline/Scanner.java
rename to commonmark/src/main/java/org/commonmark/parser/beta/Scanner.java
index 9de96a587d71896cab6d1ec9c5505d8ca8e94680..a941ef4e2b2d58046cc64a52c0fcaf004013b4cc 100644
--- a/commonmark/src/main/java/org/commonmark/internal/inline/Scanner.java
+++ b/commonmark/src/main/java/org/commonmark/parser/beta/Scanner.java
@@ -1,4 +1,4 @@
-package org.commonmark.internal.inline;
+package org.commonmark.parser.beta;
 
 import org.commonmark.internal.util.CharMatcher;
 import org.commonmark.node.SourceSpan;
diff --git a/commonmark/src/test/java/org/commonmark/internal/util/ParsingTest.java b/commonmark/src/test/java/org/commonmark/parser/beta/ParsingTest.java
similarity index 94%
rename from commonmark/src/test/java/org/commonmark/internal/util/ParsingTest.java
rename to commonmark/src/test/java/org/commonmark/parser/beta/ParsingTest.java
index f51c8647b93c38c4d7bacebe8cb8ec6adb2aeb01..85eeb7f887692ae2fcdd612ce941c7485abdc69a 100644
--- a/commonmark/src/test/java/org/commonmark/internal/util/ParsingTest.java
+++ b/commonmark/src/test/java/org/commonmark/parser/beta/ParsingTest.java
@@ -1,4 +1,4 @@
-package org.commonmark.internal.util;
+package org.commonmark.parser.beta;
 
 import org.junit.Test;
 
diff --git a/commonmark/src/test/java/org/commonmark/internal/inline/ScannerTest.java b/commonmark/src/test/java/org/commonmark/parser/beta/ScannerTest.java
similarity index 97%
rename from commonmark/src/test/java/org/commonmark/internal/inline/ScannerTest.java
rename to commonmark/src/test/java/org/commonmark/parser/beta/ScannerTest.java
index 030a765af7efd7acd894eafaca0dfafd364cb54c..668f852c4f0522b5750ab27821f5d17434b185de 100644
--- a/commonmark/src/test/java/org/commonmark/internal/inline/ScannerTest.java
+++ b/commonmark/src/test/java/org/commonmark/parser/beta/ScannerTest.java
@@ -1,8 +1,10 @@
-package org.commonmark.internal.inline;
+package org.commonmark.parser.beta;
 
 import org.commonmark.node.SourceSpan;
 import org.commonmark.parser.SourceLine;
 import org.commonmark.parser.SourceLines;
+import org.commonmark.parser.beta.Position;
+import org.commonmark.parser.beta.Scanner;
 import org.junit.Test;
 
 import java.util.Arrays;
diff --git a/pom.xml b/pom.xml
index da06b2c2b49d603005028b781fa74df094ee8b29..85aec0533f662ad359d7b2939f864c43ee63c1b4 100644
--- a/pom.xml
+++ b/pom.xml
@@ -41,6 +41,8 @@
                     <version>3.12.1</version>
                     <configuration>
                         <release>11</release>
+                        <source>9</source>
+                        <target>9</target>
                     </configuration>
                 </plugin>
                 <plugin>