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

mdcode-ts

v0.0.4

Published

TypeScript port of mdcode - Drop-in replacement for Markdown code block authoring

Readme

mdcode

A TypeScript port of szkiba/mdcode - a Markdown code block authoring tool for extracting, updating, and managing code blocks within markdown documents.

npm version

Drop-in Replacement

This TypeScript implementation is designed as a drop-in replacement for the original Go-based szkiba/mdcode. It maintains full CLI compatibility, including all commands, flags, and output formats, while adding bonus features like transform functions and a library API.

Features

  • Extract code blocks from markdown to files
  • List code blocks with metadata and previews (text or JSON format)
  • Update markdown code blocks from source files OR transform with custom functions
  • Run shell commands on code blocks with enhanced control
  • Dump code blocks to tar archives (stdout or file)
  • Support for metadata in code block info strings
  • Filter blocks by language, file, or custom metadata
  • Region extraction using special comments
  • Outline extraction for code structure
  • Quiet mode for cleaner output
  • Short and long flag forms for all options

Why Use mdcode?

The Problem

Documentation examples often become outdated. You write great examples in your README, but as your code evolves, those examples break. Users copy non-working code, get frustrated, and lose trust in your documentation.

The Solution

mdcode solves this by making your documentation executable and testable:

  1. Write code examples directly in your markdown with metadata
  2. Extract them to files for testing and development
  3. Run them as part of your test suite to ensure they actually work
  4. Update your markdown when the code changes

Key Benefits

Test Your Documentation

# Extract examples from README
mdcode extract README.md -d ./examples

# Run them as tests
mdcode run -l js "node {file}" README.md

# They work? Great! They fail? Fix them before users see broken examples.

Keep Examples Fresh

# Update your source code
nano src/calculator.js

# Sync changes back to README
mdcode update README.md

Single Source of Truth

  • Write examples once in your README
  • Extract to files for actual implementation
  • Bidirectional sync keeps everything in sync
  • No duplicate code to maintain

Documentation-Driven Development

  1. Write your README with examples first (TDD for docs)
  2. Extract code blocks to create skeleton files
  3. Implement the functionality
  4. Update README from working code
  5. Your docs are always accurate because they are the code

If your README examples don't work, the build fails. Simple.

Installation

Global Installation

Install globally to use the mdcode command anywhere:

# Using npm
npm install -g @mdcode/mdcode

# Using pnpm
pnpm install -g @mdcode/mdcode

After installation, you can run mdcode from anywhere:

mdcode --version
mdcode --help
mdcode list README.md

Run Without Installing

No installation required - run directly:

# Using pnpm dlx
pnpm dlx @mdcode/mdcode list README.md
pnpm dlx @mdcode/mdcode extract --lang js docs/*.md

# Using npx
npx @mdcode/mdcode list README.md
npx @mdcode/mdcode --help

Project Installation

Install as a project dependency to use in scripts or via pnpm exec:

# Using pnpm
pnpm add -D @mdcode/mdcode

# Using npm
npm install --save-dev @mdcode/mdcode

After installation, run via pnpm exec:

pnpm exec mdcode list README.md
pnpm exec mdcode extract --lang js docs/*.md

Or add scripts to your package.json:

{
  "scripts": {
    "readme:update": "mdcode update README.md",
    "readme:extract": "mdcode extract -d src README.md",
    "readme:list": "mdcode list --json README.md",
    "docs:validate": "mdcode run -l js \"node {file}\" README.md"
  }
}

Then run with:

pnpm readme:update
pnpm readme:extract

Local Development

pnpm install
pnpm build

CLI Usage

Default Behavior

Running mdcode without any subcommand defaults to listing code blocks from README.md:

# These are equivalent:
mdcode
mdcode list README.md

If you provide a filename without a command, it will list blocks from that file:

# These are equivalent:
mdcode docs/API.md
mdcode list docs/API.md

Get Help

# General help
mdcode --help
mdcode -h

# Command-specific help
mdcode list --help
mdcode extract --help
mdcode update --help
mdcode run --help
mdcode dump --help

Check Version

mdcode --version
mdcode -V

List Command

Display code blocks with their metadata and a preview of the content.

Basic Usage

# List all code blocks from README.md (default)
mdcode list

# List blocks from a specific file
mdcode list docs/GUIDE.md

# Read from stdin
cat README.md | mdcode list

JSON Output

Output blocks as JSON (one JSON object per line):

# JSON output
mdcode list --json README.md

# Short form
mdcode list --json docs/API.md

JSON Format:

{"lang":"js","file":"app.js","region":"main"}
{"lang":"python","file":"script.py"}
{"lang":"sql"}

Filter by Language

# Long form
mdcode list --lang js README.md
mdcode list --lang python docs/*.md

# Short form
mdcode list -l js README.md
mdcode list -l sql API.md

Filter by File Metadata

# Long form
mdcode list --file app.js README.md
mdcode list --file "*.test.js" docs/

# Short form
mdcode list -f app.js README.md
mdcode list -f server.py docs/

Filter by Custom Metadata

# Long form
mdcode list --meta region=main README.md
mdcode list --meta type=example docs/

# Short form
mdcode list -m region=main README.md
mdcode list -m type=test API.md

Multiple Filters

Combine filters to narrow results:

# All filters together
mdcode list --lang js --file app.js --meta region=main README.md

# Short forms
mdcode list -l js -f app.js -m region=main README.md

# Filter JavaScript test files
mdcode list -l js -f "*.test.js" docs/

Extract Command

Extract code blocks to files based on their file metadata.

Basic Usage

# Extract to current directory
mdcode extract README.md

# Extract from multiple files
mdcode extract docs/*.md

Custom Output Directory

# Long form
mdcode extract --dir output README.md
mdcode extract --dir ./extracted docs/API.md

# Short form
mdcode extract -d output README.md
mdcode extract -d ./build docs/

Quiet Mode

Suppress status messages (only show errors):

# Long form
mdcode extract --quiet README.md

# Short form
mdcode extract -q README.md

# Quiet with custom directory
mdcode extract -q -d output README.md

Filter What to Extract

# Extract only JavaScript files
mdcode extract --lang js README.md
mdcode extract -l js -d ./src docs/*.md

# Extract specific file
mdcode extract --file app.js README.md
mdcode extract -f server.py -d ./src docs/

# Extract with metadata filter
mdcode extract --meta type=component README.md
mdcode extract -m region=main -d ./lib docs/

Combined Examples

# Extract JavaScript files to src/ directory, quietly
mdcode extract -q -l js -d ./src README.md

# Extract Python examples to examples/ directory
mdcode extract -l python -m type=example -d ./examples docs/TUTORIAL.md

Update Source with Generated Filenames

When extracting anonymous blocks (blocks without file metadata), automatically add the generated filename back to the markdown source:

# Extract and update README with file metadata
mdcode extract --update-source README.md

# Extract to custom directory and update source
mdcode extract --update-source -d ./examples README.md

# Quiet mode
mdcode extract --update-source -q -d ./src README.md

Before:

```bash
echo "hello"
```

After:

````markdown
```bash file=block-1.sh
echo "hello"
````

This enables bidirectional sync workflow:

  1. Extract blocks: mdcode extract --update-source README.md
  2. Modify extracted files: nano block-1.sh
  3. Update markdown: mdcode update README.md

Skip Anonymous Blocks

Only extract blocks that have explicit file metadata, ignoring anonymous blocks:

# Only extract blocks with file= attribute
mdcode extract --ignore-anonymous README.md

# With filters and custom directory
mdcode extract --ignore-anonymous -l js -d ./src docs/API.md

Note: The flags --update-source and --ignore-anonymous are mutually exclusive. Using both will result in an error.

Stdin Behavior with Update Source

When using stdin with --update-source, the updated markdown is written to stdout:

# Read from stdin, output updated markdown to stdout
cat README.md | mdcode extract --update-source > updated.md

# Extract files normally, no source update
cat README.md | mdcode extract -d ./examples

Update Command

Update markdown code blocks from source files or transform them with custom functions.

Update from Source Files (Default Mode)

Updates code blocks by reading from files specified in the file metadata attribute:

# Update README.md in-place (default)
mdcode update README.md

# Output to stdout instead
mdcode update --stdout README.md

# Output to a new file
mdcode update --stdout README.md > UPDATED.md

# Read from stdin, write to stdout
cat README.md | mdcode update --stdout > UPDATED.md

Quiet Mode

# Long form
mdcode update --quiet README.md

# Short form
mdcode update -q README.md

# Quiet with output redirection
mdcode update -q --stdout README.md > UPDATED.md

Transform Mode (with Custom Function)

Transform code blocks using a custom JavaScript/TypeScript function:

# Transform with a custom function
mdcode update --transform ./transformers/uppercase-sql.js README.md

# Short form
mdcode update -t ./transformers/add-headers.js README.md

# Transform and output to file
mdcode update -t ./transformers/format-code.js --stdout README.md > output.md

Example Transformer (uppercase-sql.js):

export default function({tag, meta, code}) {
  if (tag === 'sql') {
    return code.toUpperCase();
  }
  return code;
}

Creating a TypeScript transformer:

// my-transform.ts
import { defineTransform } from 'mdcode-ts';

export default defineTransform(({tag, meta, code}) => {
  // tag: language (e.g., 'js', 'sql', 'python')
  // meta: { file?: string, region?: string }
  // code: the code block content

  if (tag === 'sql') {
    return code.toUpperCase();
  }

  if (meta.file?.includes('.test.')) {
    return `// AUTO-GENERATED\n${code}`;
  }

  return code; // return unchanged
});

Transform with Filters

Combine transformers with filters to target specific blocks:

# Transform only SQL blocks
mdcode update --transform ./uppercase.js --lang sql README.md

# Transform only test files
mdcode update -t ./add-headers.js -f "*.test.js" docs/API.md

# Transform JavaScript blocks in examples
mdcode update -t ./format.js -l js -m type=example docs/

Region Support

Update specific regions of code:

# Update only 'main' region
mdcode update --meta region=main README.md

# Update multiple regions
mdcode update -m region=setup README.md
mdcode update -m region=teardown README.md

Run Command

Execute shell commands on each code block.

Basic Usage

Use {file} as a placeholder for the temporary file path:

# Run node on JavaScript blocks
mdcode run "node {file}" --lang javascript README.md

# Run Python scripts
mdcode run "python {file}" --lang python README.md

# Compile and run C code
mdcode run "gcc {file} -o out && ./out" --lang c docs/

Filter by Language

# Long form
mdcode run --lang js "node {file}" README.md

# Short form
mdcode run -l js "node {file}" README.md

# Multiple languages (run separately)
mdcode run -l python "python {file}" docs/*.md
mdcode run -l js "node {file}" docs/*.md

Filter by Name

Filter blocks by their name metadata:

# Long form
mdcode run --name test-example "node {file}" README.md

# Short form
mdcode run -n calculate "python {file}" docs/API.md

# With language filter
mdcode run -l js -n integration-test "node {file}" tests/

Custom Working Directory

Specify where to save temporary files and run commands:

# Long form
mdcode run --dir /tmp/mdcode "node {file}" README.md

# Short form
mdcode run -d ./temp "python {file}" docs/

# With filters
mdcode run -l js -d ./build "node {file}" README.md

Keep Temporary Files

Preserve temporary directory after execution (useful for debugging):

# Long form
mdcode run --keep "node {file}" README.md

# Short form
mdcode run -k "python {file}" docs/

# The command will print the temp directory location

Combined Examples

# Run JavaScript tests with all flags
mdcode run -l js -n test -k -d ./temp "node {file}" README.md

# Run Python examples in custom directory
mdcode run -l python -m type=example -d ./examples "python {file}" docs/

# Run and keep files, filter by file metadata
mdcode run -k -f "calculator.py" "python {file}" README.md

Advanced Usage

# Lint all JavaScript blocks
mdcode run -l js "eslint {file}" README.md

# Format code blocks
mdcode run -l python "black {file}" docs/*.md

# Type check TypeScript blocks
mdcode run -l typescript "tsc --noEmit {file}" API.md

# Run tests with coverage
mdcode run -l js -n test "jest --coverage {file}" docs/

Dump Command

Create a tar archive of all code blocks.

Basic Usage (Output to stdout)

# Dump to stdout
mdcode dump README.md > code-blocks.tar

# Pipe to tar command
mdcode dump docs/*.md | tar -x

Output to File

# Long form
mdcode dump --out archive.tar README.md

# Short form
mdcode dump -o archive.tar docs/API.md

# With custom name
mdcode dump -o examples-$(date +%Y%m%d).tar README.md

Quiet Mode

# Long form
mdcode dump --quiet --out archive.tar README.md

# Short form
mdcode dump -q -o archive.tar docs/

# Quiet to stdout
mdcode dump -q README.md > archive.tar

Filter What to Dump

# Dump only JavaScript files
mdcode dump --lang js -o js-blocks.tar README.md
mdcode dump -l js -o javascript.tar docs/*.md

# Dump specific file patterns
mdcode dump --file "*.py" -o python.tar docs/
mdcode dump -f server.js -o server.tar README.md

# Dump by metadata
mdcode dump --meta type=example -o examples.tar docs/
mdcode dump -m region=main -o main.tar API.md

Extract Tar Archive

After creating a tar archive, you can extract it:

# Standard tar extraction
tar -xf code-blocks.tar

# Extract to specific directory
tar -xf code-blocks.tar -C ./extracted

# List contents without extracting
tar -tf code-blocks.tar

Filtering Examples

All commands support the same filtering options. Here are comprehensive filtering examples:

Single Filters

# By language
mdcode list -l js README.md
mdcode extract -l python docs/*.md
mdcode dump -l sql -o queries.tar API.md

# By file metadata
mdcode list -f app.js README.md
mdcode extract -f "*.test.js" docs/
mdcode run -f server.py "python {file}" README.md

# By custom metadata
mdcode list -m region=main README.md
mdcode extract -m type=example docs/
mdcode update -m author=admin API.md

Multiple Filters (AND Logic)

When you combine filters, ALL filters must match:

# Language AND file
mdcode list -l js -f app.js README.md

# Language AND metadata
mdcode extract -l python -m type=example docs/

# File AND metadata
mdcode dump -f server.js -m region=main -o server.tar README.md

# All three filters
mdcode list -l js -f app.js -m region=main README.md

Complex Filtering Scenarios

# Extract all test files that are JavaScript
mdcode extract -l js -f "*.test.js" -d ./tests docs/

# List Python examples in main region
mdcode list -l python -m type=example -m region=main docs/

# Run tests only for specific component
mdcode run -l js -f "auth.test.js" -n "login-test" "node {file}" README.md

# Update only SQL queries in specific file
mdcode update -l sql -f queries.sql README.md

CLI Flags Reference

All commands support these common filtering flags:

  • -l, --lang <lang> - Filter by language
  • -f, --file <file> - Filter by file metadata pattern
  • -m, --meta <key=value> - Filter by custom metadata (can specify multiple times)

Additional flags by command:

list:

  • --json - Output as JSON (one object per line)

extract:

  • -d, --dir <dir> - Output directory (default: current directory)
  • -q, --quiet - Suppress status messages
  • --update-source - Add file metadata to anonymous code blocks and update source
  • --ignore-anonymous - Skip blocks without file metadata (mutually exclusive with --update-source)

update:

  • -d, --dir <dir> - Working directory for file resolution
  • -q, --quiet - Suppress status messages
  • --transform <file> - Path to transformer function
  • --stdout - Output to stdout instead of updating in-place

run:

  • -n, --name <name> - Filter by block name
  • -k, --keep - Keep temporary directory
  • -d, --dir <dir> - Custom working directory

dump:

  • -o, --out <file> - Output file (default: stdout)
  • -q, --quiet - Suppress status messages

Library Usage

You can use mdcode programmatically in your Node.js or TypeScript projects:

pnpm add @mdcode/mdcode

Simple API (Default Export)

The simplest way to use mdcode is with the default export:

import mdcode from '@mdcode/mdcode';

// Transform a markdown file
const result = await mdcode('/path/to/file.md', ({tag, meta, code}) => {
  // Transform SQL to uppercase
  if (tag === 'sql') {
    return code.toUpperCase();
  }

  // Add headers to test files
  if (meta.file?.includes('.test.')) {
    return `// AUTO-GENERATED\n${code}`;
  }

  return code; // unchanged
});

console.log(result); // Transformed markdown

With filters:

// Transform only SQL blocks
const result = await mdcode(
  '/path/to/file.md',
  ({tag, meta, code}) => code.toUpperCase(),
  { lang: 'sql' }
);

Named Imports (Advanced API)

For more control, use the named exports:

import {
  parse,
  walk,
  update,
  transform,
  transformWithFunction,
  defineTransform,
  type Block,
  type TransformerFunction,
  type FilterOptions,
} from '@mdcode/mdcode';

Parse and Extract Code Blocks

import { parse } from '@mdcode/mdcode';

const markdown = `
# Example

```js file=app.js
const x = 1;
```

```python file=block-59.ts
y = 2
```
`;

// Extract all blocks
const blocks = parse({ source: markdown });
console.log(blocks); // [{ lang: 'js', code: '...', meta: { file: 'app.js' } }, ...]

// Extract with filters
const jsBlocks = parse({
  source: markdown,
  filter: { lang: 'js' }
});

Transform Code Blocks

import { update, defineTransform } from '@mdcode/mdcode';

const markdown = `
```sql
select * from users;
```

```js file=block-61.ts
test('example');
```
`;

// Create a transformer
const transformer = defineTransform(({tag, meta, code}) => {
  // Transform SQL to uppercase
  if (tag === 'sql') {
    return code.toUpperCase();
  }

  // Add headers to test files
  if (meta.file?.includes('.spec.')) {
    return `// AUTO-GENERATED TEST\n${code}`;
  }

  return code; // unchanged
});

// Apply transformation
const result = await update({ source: markdown, transformer });
console.log(result); // Transformed markdown

Async Transformers

import { update, defineTransform } from '@mdcode/mdcode';

const transformer = defineTransform(async ({tag, meta, code}) => {
  // Fetch from API, read files, etc.
  const formatted = await someAsyncFormatter(code);
  return formatted;
});

const result = await update({ source: markdown, transformer });

Custom Walker for Advanced Processing

import { walk, type Block } from '@mdcode/mdcode';

const result = await walk({
  source: markdown,
  walker: async (block: Block) => {
    // Return modified block
    return { ...block, code: block.code.toUpperCase() };

    // Or return null to remove block
    // return null;
  },
  filter: { lang: 'js' }, // Optional filter
});

console.log(result.source);   // Modified markdown
console.log(result.blocks);   // All processed blocks
console.log(result.modified); // true if any changes were made

Filter Options

All functions support filtering:

// Filter by language
parse({ source: markdown, filter: { lang: 'js' } });

// Filter by file pattern
parse({ source: markdown, filter: { file: 'app.js' } });

// Filter by custom metadata
parse({ source: markdown, filter: { meta: { region: 'main' } } });

// Combine filters
update({
  source: markdown,
  transformer,
  filter: { lang: 'sql', file: 'queries.sql' }
});

API Reference

parse(options: ParseOptions): Block[]

Extract code blocks from markdown.

  • options.source - The markdown source string
  • options.filter - Optional filter criteria
  • Returns - Array of Block objects

walk(options: WalkOptions): Promise<WalkResult>

Walk through and optionally transform code blocks.

  • options.source - The markdown source string
  • options.walker - Function called for each block
  • options.filter - Optional filter criteria
  • Returns - Promise of WalkResult with source, blocks, and modified flag

update(options: UpdateOptions): Promise<string>

Update code blocks from files or via transformer.

  • options.source - The markdown source string
  • options.transformer - Optional transformer function
  • options.filter - Optional filter criteria
  • options.basePath - Base path for file resolution (default: '.')
  • Returns - Promise of transformed markdown string

transformWithFunction(source: string, transformer: TransformerFunction, filter?: FilterOptions): Promise<string>

Transform code blocks using a transformer function.

  • source - The markdown source string
  • transformer - Transformer function
  • filter - Optional filter criteria
  • Returns - Promise of transformed markdown string

defineTransform(fn: TransformerFunction): TransformerFunction

Helper to define type-safe transformers.

  • fn - The transformer function ({tag, meta, code}) => string | Promise<string>
  • Returns - The same function with proper typing

Metadata in Code Blocks

Add metadata to code blocks using the info string:

```js file=hello.js region=main
console.log('Hello, world!');
```

Supported metadata:

  • file: Output filename for extraction
  • region: Region name for partial extraction (using #region/#endregion comments)
  • outline: Extract only the structure without implementation details
  • name: Custom name for the block (useful with run command)
  • Custom key=value pairs for filtering

Region Extraction

Use region comments in your source files to extract specific sections. If the same region name appears multiple times, all occurrences are joined together:

// #region factorial
function factorial(n) {
  if (n <= 1) return 1;
  return n * factorial(n - 1);
}
// #endregion

// #region helper
function helper() { /* ... */ }
// #endregion

Region markers are detected using language-appropriate comment styles (e.g. // for JS/TS, # for Python/Shell, <!-- for HTML). Specify the lang in the code fence to enable language-aware matching.

Then reference the region in your markdown:

```js file=math.js region=factorial
```

Outline Extraction

Use outline=true to extract code structure without implementation details:

```js file=calculator.js outline=true
```

When updating from source, this will preserve the region markers and structure but remove the implementation:

// #region add
// #endregion

// #region subtract
// #endregion

This is useful for documentation that shows structure without implementation details.


Comparison with Original mdcode

This TypeScript implementation is a drop-in replacement for the original Go-based szkiba/mdcode. It maintains 100% CLI compatibility.

Feature Parity

| Feature | Original (Go) | This Implementation | |---------|---------------|---------------------| | list command |  |  | | extract command |  |  | | update command |  |  | | run command |  |  | | dump command |  |  | | Short flags (-l, -f, -m) |  |  | | Long flags (--lang, --file) |  |  | | JSON output (--json) |  |  | | Quiet mode (-q, --quiet) |  |  | | Default behavior (list README.md) |  |  | | Stdin support |  |  | | Region extraction |  |  | | Outline support |  |  | | Transform functions | L |  (Bonus) | | Library API | L |  (Bonus) |

Command Compatibility

All commands work identically:

# Original (Go)
mdcode list -l js README.md
mdcode extract -d output -q docs/*.md
mdcode run -l python "python {file}" README.md
mdcode dump -o archive.tar README.md

# This implementation (TypeScript) - SAME COMMANDS
mdcode list -l js README.md
mdcode extract -d output -q docs/*.md
mdcode run -l python "python {file}" README.md
mdcode dump -o archive.tar README.md

Bonus Features

These features are not in the original but are available in this implementation:

  1. Transform Functions - Apply custom transformations to code blocks

    mdcode update --transform ./uppercase.js -l sql README.md
  2. Library API - Use mdcode programmatically in Node.js/TypeScript projects

    import mdcode from '@mdcode/mdcode';
    const result = await mdcode('README.md', transformer);
  3. Enhanced Update - Update command supports both file-based updates AND transformers


Workflow Examples

Workflow: Extract, Modify, Update

# 1. Extract code blocks to files
mdcode extract -d ./readme README.md

# 2. Edit the extracted files
nano ./readme/app.js

# 3. Update README with changes
mdcode update README.md

Workflow: Test All Code Blocks

# Extract test files
mdcode extract -l js -f "*.test.js" -d ./tests docs/

# Run all tests
mdcode run -l js -f "*.test.js" "npm test {file}" docs/

# If tests pass, create archive
mdcode dump -l js -f "*.test.js" -o tests.tar docs/

Workflow: Transform and Publish

# Transform SQL to uppercase
mdcode update -t ./uppercase.js -l sql README.md

# Verify changes
mdcode list --json -l sql README.md

# Extract transformed code
mdcode extract -l sql -d ./queries README.md

Development

Run tests

# All tests (unit + E2E)
pnpm test:all

# Unit tests only
pnpm test

Build

pnpm build

Run directly (Node 22+)

node packages/mdcode/src/main.ts list README.md

License

MIT

Credits

Original Go implementation by szkiba