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 🙏

© 2025 – Pkg Stats / Ryan Hefner

depyo

v1.0.2

Published

Python bytecode decompiler (Python 1.0–3.14) implemented in Node.js

Readme

depyo — Python bytecode decompiler in Node.js

Depyo converts Python .pyc files (or archives of them) back to readable Python source. It aims for broad coverage (Python 1.0 through 3.14) and fast throughput, with fixtures for modern features (exception groups, pattern matching, walrus, f-strings, async, context managers).

Why depyo?

  • Wide version coverage: Opcode tables and expected outputs for Python 1.0–3.14, plus decompilation support for PyPy bytecode sets.
  • Modern features: WITH_EXCEPT_START/PREP_RERAISE_STAR, async/await, walrus, match/case, f-strings, type params, dict/set merges.
  • Workflow friendly: CLI options for asm dumps, raw spacing hints, raw .pyc preservation, and flattened output paths.
  • Verification harness: run-fixtures.js and run-matrix.js compare decompiled output against expected fixtures across versions.

Install

  • Global: npm i -g depyo
  • One-off: npx depyo <file.pyc>

Node.js 20+ recommended (matches CI).

Quick start

# Decompile a single .pyc
node depyo.js /path/to/file.pyc

# Decompile a zip of .pyc files, emit asm and keep raw bytes
node depyo.js --asm --raw my_archive.zip

# Write sources next to inputs (skip directory mirroring)
node depyo.js --skip-path /path/to/file.pyc

# Dump to stdout instead of files
node depyo.js --out /path/to/file.pyc

# Marshal-only blob (no .pyc header)
node depyo.js --marshal --py-version 3.11 /path/to/blob.bin
node depyo.js --marshal /path/to/blob.bin

# Fast marshal scan (no decompile)
node depyo.js --marshal-scan /path/to/blob.bin

Without --py-version, depyo scans supported versions (oldest → newest) and accepts the first clean output when all clean candidates agree. If outputs diverge (ambiguous), it stops and asks for --py-version. Use --debug to see scan results.

CLI options

  • --asm emit .pyasm disassembly alongside source
  • --raw emit raw .pyc next to output
  • --raw-spacing preserve blank lines/comment gaps
  • --dump dump marshalled object tree
  • --stats print throughput stats
  • --skip-source-gen skip writing .py (use with --asm/--dump)
  • --skip-path flatten output paths (write next to input)
  • --out print source to stdout instead of files
  • --marshal treat input as raw marshalled data (no .pyc header, auto-scan versions)
  • --marshal-scan fast scan marshal blobs and print version candidates
  • --py-version <x.y> bytecode version hint (use with --marshal)
  • --basedir <dir> override output root (default: alongside input)
  • --file-ext <ext> change emitted extension (default py)

Examples

  • Disassemble only (no source): node depyo.js --skip-source-gen --asm file.pyc
  • Keep raw + disassembly next to source: node depyo.js --raw --asm path/to/file.pyc
  • Flatten outputs (helpful for bulk zips): node depyo.js --skip-path archive.zip

Testing

  • Smoke per version:
    node scripts/run-fixtures.js --root test/bytecode_3.14 --pattern py314_with_except_star --fail-fast
    node scripts/run-fixtures.js --root test/bytecode_3.6 --pattern py36_fstrings --fail-fast
  • Matrix (all versions, optional PyPy):
    node scripts/run-matrix.js                  # full sweep
    node scripts/run-matrix.js --pattern py311_exception_groups --fail-fast
  • Marshal fixtures (headerless marshal blobs):
    node scripts/run-marshal-fixtures.js
  • Regenerate marshal fixtures:
    node scripts/generate-marshal-fixtures.js --clean
  • Modern fixtures are generated via test/generate_modern_tests.py (Python 3.8+ on PATH).

Support matrix

  • Python 1.0–3.14 opcode tables with expected fixtures.
  • Modern features: match/case, walrus, f-strings, exception groups, type params.
  • PyPy bytecode sets decompile; expected files are not yet part of CI.
  • Legacy CI smokes (1.x/2.7/3.0–3.6) are informational (continue-on-error); modern feature checks are blocking.

Known limitations

  • Inline comprehensions (Python 3.12+): PEP 709 inlines list/dict/set comprehensions into parent code objects. Depyo currently reconstructs these as for-loops rather than comprehension expressions. Functions, classes, match/case, exception handling, and other constructs work correctly.

Contributing / DX tips

  • Use node scripts/run-fixtures.js --pattern <piece> for fast repros.
  • For full coverage, node scripts/run-matrix.js --fail-fast (optionally add --pattern).
  • Enable --raw-spacing to inspect potential comment/blank-line gaps.
  • --stats helps when profiling throughput.

Comments and docs are in English; output mirrors the target Python version syntax.

Comparison snapshot (at a glance)

| Project | Supported versions | Modern features (match, walrus, f-strings, exc groups) | Delivery | Expected fixtures | Notes | | ------------------ | --------------------------- | ------------------------------------------------------ | ------------ | ----------------- | ----------------------------------------- | | depyo | 1.0–3.14 (PyPy decompiles) | Yes | npm/npx, CLI | Yes (1.0–3.14) | Node.js CLI, asm/raw-spacing options | | uncompyle6/decompyle3 | 2.x–3.12+ (lag on 3.13/3.14) | Partial (depends on branch) | pip | Partial | Python-based, slower adoption of new ops | | pycdc (C++) | Mostly 2.x–3.x (limited new) | Partial | source build | No | Fast, but modern coverage limited |

Quick benchmark (informal)

  • Machine: local Node 25, single-thread.
  • Case: py314_exception_groups.pyc decompiled 50× in-process: ~5.3 ms total (≈0.1 ms per decompile).
    Use node depyo.js --stats <file.pyc> for your environment.

Promotion ideas (OSS)

  • Announce on HN/Reddit (Show HN / r/Python) with npm/npx one-liners.
  • Add to awesome lists (awesome-python, awesome-reverse-engineering).
  • Provide asciinema/GIF of npx depyo file.pyc + --asm.
  • Encourage contributions via Issues/Discussions and help wanted labels.