···77## What it looks like
8899```mlf
1010-namespace com.example.post {
1111- record post {
1212- text: string constrained {
1313- maxLength: 3000,
1414- maxGraphemes: 300,
1515- },
1616- createdAt: Datetime,
1717- reply?: replyRef,
1818- }
1919-2020- alias replyRef = {
2121- root: com.atproto.repo.strongRef,
2222- parent: com.atproto.repo.strongRef,
2323- };
1010+record post {
1111+ text!: string constrained {
1212+ maxLength: 3000,
1313+ maxGraphemes: 300,
1414+ },
1515+ createdAt!: Datetime,
1616+ reply: replyRef,
2417}
1818+1919+def type replyRef = {
2020+ root!: com.atproto.repo.strongRef,
2121+ parent!: com.atproto.repo.strongRef,
2222+};
2523```
26242725## Getting started
···6866```bash
6967mlf validate examples/app.bsky.feed.post.mlf record.json
7068```
6969+7070+### Convert JSON lexicons to MLF
7171+7272+Convert existing ATProto JSON lexicons to MLF format:
7373+7474+```bash
7575+# Convert a single lexicon
7676+mlf generate mlf -i my-lexicon.json -o ./
7777+7878+# Convert multiple lexicons
7979+mlf generate mlf -i "dist/lexicons/**/*.json" -o src/lexicons/
8080+```
8181+8282+This is useful for:
8383+- Migrating existing JSON lexicons to the MLF format
8484+- Learning MLF syntax by comparing JSON and MLF
8585+- Working with lexicons from external sources
71867287## Project layout
7388
+18
SPEC.md
···716716mlf generate lexicon --input "**/*.mlf" lexicons/*
717717mlf generate example --input "**/*.mlf" --count 5 examples/*
718718719719+# Convert JSON lexicons to MLF
720720+mlf generate mlf --input "lexicons/**/*.json" --output ./mlf/
721721+719722# Validate lexicons
720723mlf validate <files|globs>
721724mlf validate "**/*.mlf"
···726729# Validate a record against a lexicon
727730mlf check --input app.bsky.feed.post.mlf ./record.json
728731```
732732+733733+### JSON to MLF Conversion
734734+735735+The `mlf generate mlf` command converts ATProto JSON lexicons back to MLF format. This is useful for:
736736+737737+- **Migration**: Converting existing JSON lexicons to MLF
738738+- **Interoperability**: Working with lexicons from external sources
739739+- **Learning**: Seeing how JSON lexicons map to MLF syntax
740740+- **Comparison**: Generating MLF from JSON to compare with hand-written MLF
741741+742742+The converter automatically:
743743+- Converts format strings (did, datetime, handle) to prelude types (Did, Datetime, Handle)
744744+- Properly formats required (`!`) and optional (default) fields
745745+- Converts `namespace#name` references to `namespace.name` notation
746746+- Generates clean, properly indented MLF with correct syntax
729747730748## Examples
731749
+89
website/content/docs/cli.md
···235235236236---
237237238238+### `mlf generate mlf`
239239+240240+Convert ATProto JSON lexicons back to MLF format.
241241+242242+```bash
243243+mlf generate mlf --output <OUTPUT> [OPTIONS]
244244+```
245245+246246+**Options:**
247247+- `-i, --input <INPUT>` - Input JSON lexicon files (glob patterns supported, can be specified multiple times)
248248+- `-o, --output <OUTPUT>` - Output directory (required)
249249+250250+**Examples:**
251251+252252+```bash
253253+# Convert a single JSON lexicon to MLF
254254+mlf generate mlf -i com.example.thread.json -o ./lexicons/
255255+# Creates: lexicons/com/example/thread.mlf
256256+257257+# Convert multiple JSON lexicons
258258+mlf generate mlf -i lexicon1.json -i lexicon2.json -o ./mlf/
259259+260260+# Convert using glob pattern
261261+mlf generate mlf -i "dist/lexicons/**/*.json" -o ./src/
262262+```
263263+264264+**Features:**
265265+266266+- **Smart type conversion** - Automatically converts format strings (did, datetime, handle) to prelude types (Did, Datetime, Handle)
267267+- **Proper formatting** - Generates clean, properly indented MLF with correct syntax
268268+- **Reference conversion** - Converts `namespace#name` refs to `namespace.name` notation
269269+- **Complete coverage** - Supports records, queries, procedures, subscriptions, tokens, and type definitions
270270+271271+**Input format:**
272272+273273+The JSON lexicon must be a valid ATProto lexicon with:
274274+- `lexicon: 1` version field
275275+- `id` field containing the namespace
276276+- `defs` object with type definitions
277277+278278+**Example:**
279279+280280+Given a JSON lexicon:
281281+```json
282282+{
283283+ "lexicon": 1,
284284+ "id": "com.example.thread",
285285+ "defs": {
286286+ "main": {
287287+ "type": "record",
288288+ "key": "tid",
289289+ "record": {
290290+ "type": "object",
291291+ "required": ["title", "createdAt"],
292292+ "properties": {
293293+ "title": {
294294+ "type": "string",
295295+ "maxLength": 200
296296+ },
297297+ "createdAt": {
298298+ "type": "string",
299299+ "format": "datetime"
300300+ }
301301+ }
302302+ }
303303+ }
304304+ }
305305+}
306306+```
307307+308308+Generates MLF:
309309+```mlf
310310+record main {
311311+ title!: string constrained {
312312+ maxLength: 200,
313313+ },
314314+ createdAt!: Datetime,
315315+};
316316+```
317317+318318+**Use cases:**
319319+320320+- **Migration** - Convert existing JSON lexicons to MLF format
321321+- **Interoperability** - Work with lexicons from other tools or repositories
322322+- **Comparison** - Generate MLF from JSON to compare with hand-written MLF
323323+- **Learning** - See how JSON lexicons translate to MLF syntax
324324+325325+---
326326+238327## Error Messages
239328240329MLF provides rich error messages with:
+14-1
website/content/docs/getting-started.md
···8181mlf validate thread.mlf record.json
8282```
83838484+## Convert JSON Lexicons to MLF
8585+8686+Already have ATProto JSON lexicons? Convert them to MLF format:
8787+8888+```bash
8989+mlf generate mlf -i my-lexicon.json -o ./
9090+```
9191+9292+This is useful for:
9393+- Migrating existing lexicons to MLF
9494+- Learning MLF syntax by seeing JSON conversions
9595+- Working with lexicons from other sources
9696+8497## Next Steps
85988686-- Read the [Syntax Guide](./syntax.md) to learn the MLF language
9999+- Read the [Language Guide](./language-guide/) to learn the MLF language
87100- Check out the [CLI Reference](./cli.md) for all commands
88101- Try the [WASM API](./wasm.md) to use MLF in the browser