Mkpfs

Latest version: v1.0.0

Safety actively analyzes 1006753 Python packages for vulnerabilities to keep your Python projects secure.

Scan your dependencies

Page 1 of 2

1.0.0

🤖 What's Changed

- Several improvements and fixes related to image packing, unpacking, and verification.
- Implemented a simple GUI.

🚀 Quick Start

bash
Install/Update using pip
python -m pip install -U "mkpfs"

Creating Images: Option 1: .exfat -> .ffpfsc (Works with ShadowMountPlus) (Maximum compatibility)
python -m mkpfs pack file './BREW1234.exfat' './BREW1234.ffpfsc'

Creating Images: Option 2: .ffpkg -> .ffpfsc (Works with ShadowMountPlus)
python -m mkpfs pack file './BREW1234.ffpkg' './BREW1234.ffpfsc'

Creating Images: Option 3: Game folder -> .ffpfsc in one pass (default: exFAT-wrapped, no temp file)
python -m mkpfs pack folder './BREW1234-app' './BREW1234.ffpfsc'

Creating Images: Option 4: Game folder packed directly as PFS (advanced single-pass)
python -m mkpfs pack folder --raw './BREW1234-app/' './BREW1234.ffpfs'

Creating Images: Option 5: Game folder wrapped twice into PFS (advanced two-pass)
python -m mkpfs pack folder --raw --no-compress --no-adjust-output-file-extension './BREW1234-app' './pfs_image.dat'
python -m mkpfs pack file './pfs_image.dat' './BREW1234.ffpfsc'
rm './pfs_image.dat'

Extracting Existing Images (Reverse operation; --deep lists/extracts inside a wrapped exFAT)
python -m mkpfs unpack --deep './BREW1234.ffpfsc' './BREW1234-extracted/'


⚠️ Limitations and Known Issues

- `exfat->ffpfsc` is the most stable format for compressed game backups. `pack folder` produces this layout by
default: it wraps the folder in an exFAT image and compresses that into the `.ffpfsc` in a single pass, with no
temporary `.exfat` on disk.
- `pack folder --raw` packs the folder directly into a PFS image without the exFAT wrapper. When file compression is
enabled, the image is created and verification passes, but the console reads the files incorrectly due to technical
limitations, so this advanced option provides no practical benefit for game backups. Prefer the default wrapped
layout.
- With the default `--block-size 65536`, very small files can cause significant block-alignment waste, which may make
the resulting image larger than the source in corner cases.
- For small-file-heavy folders, prefer the two-pass strategy (`raw-folder -> .dat -> .ffpfsc`) or try a smaller
block size such as `--block-size 16384` or `--block-size 32768`.
- Antivirus scanning can reduce conversion speed, especially during the write phase or when processing many loose
files. If you trust this software in your environment and need higher throughput, temporarily disabling real-time
scanning can help. If you are unsure, keep antivirus enabled and expect slower conversions.

💖 Sponsorship

MkPFS is easier to sustain when users who benefit from it help fund it.

<p>
<a href="https://github.com/sponsors/RenanGBarreto">
<img alt="GitHub Sponsors" src="https://img.shields.io/badge/Fund%20Development-GitHub%20Sponsors-e11d48?style=flat-square&logo=githubsponsors&logoColor=white" />
</a>
</p>

☕ Contributions

Breaking

* Add graphical interface prototype (73) RenanGBarreto, Phoenixx1202

New

* Add verbose per-item output and guardrails to batch convert (118) RenanGBarreto
* Default exFAT cluster to 64 KiB (109) RenanGBarreto
* Add batch conversion support for converting multiple games with a single command (100) RenanGBarreto, [dependabot[bot]](https://github.com/apps/dependabot)
* Perfomance Improvement: Add compression backend adapter module with ISAL support (93) RenanGBarreto, Copilot
* Add Pack exFAT panel and sync GUI progress (89) RenanGBarreto
* Skip AMPR index regeneration when a valid index already exists (88) RenanGBarreto
* Set default compression level to 7 (87) RenanGBarreto

Bug Fixes

* Use native monospaced font on macOS and Linux (119) RenanGBarreto
* Fix exfat panel crash and remove dead UI options (111) RenanGBarreto
* Fix macOS GUI build to bundle customtkinter and set installer title (80) RenanGBarreto

Maintenance

* Fix silent mode fallthrough, private CTkTextbox API access, missing hover feedback, and multi-size ICO generation (102) [copilot-swe-agent[bot]](https://github.com/apps/copilot-swe-agent), Copilot, RenanGBarreto
* Fix icon generation crash with newer Pillow versions (98) RenanGBarreto
* Catch only Pillow import failures in icon generation (91) [copilot-swe-agent[bot]](https://github.com/apps/copilot-swe-agent), Copilot
* Complete contributor update map and normalize `./tmp/` path (90) [copilot-swe-agent[bot]](https://github.com/apps/copilot-swe-agent), Copilot
* Split the monolith gui.py into a focused package (84) RenanGBarreto
* Make docs/skills easier to discover and follow, reduce duplication (72) RenanGBarreto
* Streamline rules, add worktree map, and expand related-projects index (71) RenanGBarreto

Dependency Updates

<details>
<summary>12 changes</summary>

* chore(deps-dev): bump ruff from 0.16.1 to 0.16.4 (116) [dependabot[bot]](https://github.com/apps/dependabot)
* chore(deps): bump actions/setup-python from 6 to 7 (105) [dependabot[bot]](https://github.com/apps/dependabot), RenanGBarreto
* chore(deps-dev): bump ruff from 0.16.0 to 0.16.1 (108) [dependabot[bot]](https://github.com/apps/dependabot)
* chore(deps): bump actions/stale from 10 to 11 (107) [dependabot[bot]](https://github.com/apps/dependabot), RenanGBarreto
* chore(deps-dev): bump ruff from 0.15.21 to 0.16.0 (106) [dependabot[bot]](https://github.com/apps/dependabot)
* chore(deps-dev): bump ruff from 0.15.20 to 0.15.21 (96) [dependabot[bot]](https://github.com/apps/dependabot)
* chore(deps-dev): update hatchling requirement from <1.30 to <1.32 (97) [dependabot[bot]](https://github.com/apps/dependabot)
* chore(deps): bump actions/setup-python from 4 to 6 (82) [dependabot[bot]](https://github.com/apps/dependabot)
* chore(deps): bump actions/checkout from 4 to 7 (74) [dependabot[bot]](https://github.com/apps/dependabot)
* chore(deps): bump actions/upload-artifact from 6 to 7 (76) [dependabot[bot]](https://github.com/apps/dependabot)
* chore(deps): bump actions/download-artifact from 6 to 8 (75) [dependabot[bot]](https://github.com/apps/dependabot)
* chore(deps): bump pozil/auto-assign-issue from 1 to 4 (77) [dependabot[bot]](https://github.com/apps/dependabot)
</details>

Other changes

* Handle StrEnum import for different Python versions (115) cocoon
* GUI: Auto populate output form fields (110) RenanGBarreto
* Faster file discovery for large source trees (86) RenanGBarreto
* Consolidate rules into CLAUDE.md and fix broken agent paths (85) RenanGBarreto

**Full Changelog**: https://github.com/PSBrew/MkPFS/compare/0.0.9...1.0.0



<details>
<summary>🛡 VirusTotal analysis</summary>

* [`mkpfs-1.0.0-linux-x64.AppImage`](https://www.virustotal.com/gui/file-analysis/YzQzMGZhOWU1MmQ2YjkyMzQ3YTAwYzc0YzY0ZDMwODU6MTc4ODQxMDQ5MA==/detection)
* [`mkpfs-1.0.0-linux-x64.tar.gz`](https://www.virustotal.com/gui/file-analysis/ZTBkNGJlNDU4YzhkOGM2NWNiZDUwY2NiZGViZDg0OWQ6MTc4ODQxMDQ5NQ==/detection)
* [`mkpfs-1.0.0-macos-arm64.pkg`](https://www.virustotal.com/gui/file-analysis/OTVmNmEyMWIwNTBmYTMyODgxNjNmOWFkMjEzYjE0NTg6MTc4ODQxMDUwMA==/detection)
* [`mkpfs-1.0.0-py3-none-any.whl`](https://www.virustotal.com/gui/file-analysis/ZWYxMmRjMmI3MTJiMTgzYTRmMWQxNDc5NmM1N2U1ZWI6MTc4ODQxMDUwMg==/detection)
* [`mkpfs-1.0.0-windows-x64.exe`](https://www.virustotal.com/gui/file-analysis/ODlkMmRjNjNmOTcyYmZlNjE5ZWYyNTU1YzlkYTIwNmU6MTc4ODQxMDU1MA==/detection)
* [`mkpfs-1.0.0.tar.gz`](https://www.virustotal.com/gui/file-analysis/MTkxZWZiNzUxOTJlMWVkZjE5YjMwOGNmMTllMTQ4OGY6MTc4ODQxMDU1Mg==/detection)
<sub>These scans were produced by the [VirusTotal GitHub Action](https://github.com/crazy-max/ghaction-virustotal)</sub></details>

0.0.9

🤖 What's Changed

- Add full exFAT support: pure-Python exFAT writer/reader and a new pack exfat command (create raw .exfat images).
- Default pack folder now produces an exFAT-wrapped .ffpfsc (more compatible); keep --raw to opt out and pack PFS directly.
- Unpack/verify/tree now understand wrapped exFAT images:
- tree --deep lists files inside a wrapped exFAT
- unpack --deep --only lets you cherry-pick files/folders from a wrapped exFAT
- verify can compare/inspect exFAT images
- Performance improvements: multicore compression for the fused exFAT path and faster unpacking (zlib-ng backend).
- Stability and memory safety: bound in-flight blocks in the multi-worker PFSC encoder to cap memory usage.
- Sanity fixes: exclude OS-generated metadata from source/image verification comparisons.
- Quality-of-life: option to hide progress bars on some commands, various docs/README updates and dependency upgrades.

🚀 Quick Start

bash
Install/Update using pip
python -m pip install -U "mkpfs"

Creating Images: Option 1: .exfat -> .ffpfsc (Works with ShadowMountPlus) (Maximum compatibility)
python -m mkpfs pack file './BREW1234.exfat' './BREW1234.ffpfsc'

Creating Images: Option 2: .ffpkg -> .ffpfsc (Works with ShadowMountPlus)
python -m mkpfs pack file './BREW1234.ffpkg' './BREW1234.ffpfsc'

Creating Images: Option 3: Game folder -> .ffpfsc in one pass (default: exFAT-wrapped, no temp file)
python -m mkpfs pack folder './BREW1234-app' './BREW1234.ffpfsc'

Creating Images: Option 4: Game folder packed directly as PFS (advanced single-pass)
python -m mkpfs pack folder --raw './BREW1234-app/' './BREW1234.ffpfs'

Creating Images: Option 5: Game folder wrapped twice into PFS (advanced two-pass)
python -m mkpfs pack folder --raw --no-compress --no-adjust-output-file-extension './BREW1234-app' './pfs_image.dat'
python -m mkpfs pack file './pfs_image.dat' './BREW1234.ffpfsc'
rm './pfs_image.dat'

Extracting Existing Images (Reverse operation; --deep lists/extracts inside a wrapped exFAT)
python -m mkpfs unpack --deep './BREW1234.ffpfsc' './BREW1234-extracted/'


⚠️ Limitations and Known Issues

- `exfat->ffpfsc` is the most stable format for compressed game backups. `pack folder` produces this layout by
default: it wraps the folder in an exFAT image and compresses that into the `.ffpfsc` in a single pass, with no
temporary `.exfat` on disk.
- `pack folder --raw` packs the folder directly into a PFS image without the exFAT wrapper. When file compression is
enabled, the image is created and verification passes, but the console reads the files incorrectly due to technical
limitations, so this advanced option provides no practical benefit for game backups. Prefer the default wrapped
layout.
- With the default `--block-size 65536`, very small files can cause significant block-alignment waste, which may make
the resulting image larger than the source in corner cases.
- For small-file-heavy folders, prefer the two-pass strategy (`raw-folder -> .dat -> .ffpfsc`) or try a smaller
block size such as `--block-size 16384` or `--block-size 32768`.
- Antivirus scanning can reduce conversion speed, especially during the write phase or when processing many loose
files. If you trust this software in your environment and need higher throughput, temporarily disabling real-time
scanning can help. If you are unsure, keep antivirus enabled and expect slower conversions.

💖 Sponsorship

MkPFS is easier to sustain when users who benefit from it help fund it.

<p>
<a href="https://github.com/sponsors/RenanGBarreto">
<img alt="GitHub Sponsors" src="https://img.shields.io/badge/Fund%20Development-GitHub%20Sponsors-e11d48?style=flat-square&logo=githubsponsors&logoColor=white" />
</a>
</p>

☕ Contributions

Other changes

* Add an option to hide progress bar in some commands (70) RenanGBarreto
* Add support to unpack, verify, and list files from exfat images (68) RenanGBarreto
* Platform-independent exFAT: pure-Python writer/reader, one-pass pack folder, deep read (65) rdmrocha
* AMPR emulation automated index and OS-metadata exclusion for folder packing (63) rdmrocha
* Faster unpack compression backend (62) rdmrocha
* Fix pack file command defaults and documentation (59) RenanGBarreto
* Improved logging (58) RenanGBarreto

**Full Changelog**: https://github.com/PSBrew/MkPFS/compare/0.0.8...0.0.9

0.0.8

🤖 What's Changed

- Several improvements and fixes related to image packing, unpacking, and verification.
- Added warnings to let the user know when they use experimental flag combinations
- Automatically rename inner image to avoid bad special characters introduced by the user

🚀 Quick Start

bash
Install/Update using pip
python -m pip install -U "mkpfs"

Creating Images: Option 1: .exfat -> .ffpfsc (Works with ShadowMountPlus) (Maximum compatibility)
python -m mkpfs pack file './BREW1234.exfat' './BREW1234.ffpfsc'

Creating Images: Option 2: .ffpkg -> .ffpfsc (Works with ShadowMountPlus)
python -m mkpfs pack file './BREW1234.ffpkg' './BREW1234.ffpfsc'

Creating Images: Option 3: Game folder wrapped twice into .ffpfsc (two-pass) (Works with ShadowMountPlus)
python -m mkpfs pack folder --no-compress --no-adjust-output-file-extension './BREW1234-app' './pfs_image.dat'
python -m mkpfs pack file './pfs_image.dat' './BREW1234.ffpfsc'
rm './pfs_image.dat'

Creating Images: Option 4: Game folder without a wrapper (single-pass) (--no-compress) (Avoid; See Notes!)
python -m mkpfs pack folder --no-compress './BREW1234-app/' './BREW1234.ffpfs'

Extracting Existing Images (Reverse operation)
python -m mkpfs unpack './BREW1234.ffpfs' './BREW1234-extracted/'


⚠️ Limitations and Known Issues

- `exfat->ffpfsc` is currently the most stable format for compressed game backups.
- Packing an application folder directly into an image without a wrapper (single-pass) does not work when
file compression is enabled. Although the image is created and verification passes, the console reads the files
incorrectly due to technical limitations, so this option provides no practical benefit.
- With the default `--block-size 65536`, very small files can cause significant block-alignment waste, which may make
the resulting image larger than the source in corner cases.
- For small-file-heavy folders, prefer the two-pass strategy (`raw-folder -> .dat -> .ffpfsc`) or try a smaller
block size such as `--block-size 16384` or `--block-size 32768`.
- Antivirus scanning can reduce conversion speed, especially during the write phase or when processing many loose
files. If you trust this software in your environment and need higher throughput, temporarily disabling real-time
scanning can help. If you are unsure, keep antivirus enabled and expect slower conversions.

💖 Sponsorship

MkPFS is easier to sustain when users who benefit from it help fund it.

<p>
<a href="https://github.com/sponsors/RenanGBarreto">
<img alt="GitHub Sponsors" src="https://img.shields.io/badge/Fund%20Development-GitHub%20Sponsors-e11d48?style=flat-square&logo=githubsponsors&logoColor=white" />
</a>
</p>

☕ Contributions

Other changes

* feat(cli): stream pack files by default, add --use-spool opt-out (54) RenanGBarreto
* Make post-pack verification much faster by default (53) RenanGBarreto
* Add warnings and make compression task more stable for remote volumes (52) RenanGBarreto
* Fix inner image names that could break mounts (51) RenanGBarreto
* Warn when packing game/app folders directly with compression enabled or invalid configs (48) RenanGBarreto

**Full Changelog**: https://github.com/PSBrew/MkPFS/compare/0.0.7...0.0.8

0.0.7

🤖 What's Changed

- Several improvements and fixes related to image packing, unpacking, and verification.
- **IMPORTANT:** This version fixes a major bug related to compressing game backup folders (methods 3 and 4 below).
- ⚠️ **At this time, converting a game backup with `exfat -> ffpfsc` (method 1) remains the most stable workflow.**
- Direct conversion from a game folder may work for some titles, but it is still experimental.
- The conversion methods below are ordered from best to worst.
- If you run into issues, please report them at: https://github.com/PSBrew/MkPFS/issues

🚀 Quick Start

bash
Install/Update using pip
python -m pip install -U "mkpfs"

Creating Images: Option 1: .exfat -> .ffpfsc (Works with ShadowMountPlus) (Maximum compatibility)
python -m mkpfs pack file --verify './BREW1234.exfat' './BREW1234.exfat.ffpfsc'

Creating Images: Option 2: .ffpkg -> .ffpfsc (Works with ShadowMountPlus)
python -m mkpfs pack file --verify './BREW1234.ffpkg' './BREW1234.ffpkg.ffpfsc'

Creating Images: Option 3: Game folder wrapped twice into .ffpfsc (two-pass) (Works with ShadowMountPlus)
python -m mkpfs pack folder --verify --no-compress --no-adjust-output-file-extension './BREW1234-app' './pfs_image.dat'
python -m mkpfs pack file --verify './pfs_image.dat' './BREW1234.ffpfsc'
rm './pfs_image.dat'

Creating Images: Option 4: Game folder without a wrapper (single-pass) (UNSTABLE) (Works with ShadowMountPlus)
python -m mkpfs pack folder --verify './BREW1234-app/' './BREW1234.ffpfsc'

Extracting Existing Images (Reverse operation)
python -m mkpfs unpack './BREW1234.ffpfs' './BREW1234-extracted/'


**Note on conversion speed:**

- Antivirus scanning can reduce conversion speed, especially during the writing phase or when processing many loose files.
If you plan to convert many titles in bulk and you trust this software in your environment, you may temporarily disable
real-time antivirus protection to speed up the process. If you are unsure, keep antivirus enabled and expect slower conversions.

**Notes on stability:**

- `exfat->ffpfsc` is the most stable solution at this moment.
- raw folder compression works, but has limitations for large game backups or if the folder contains too many small files. In that case, use `exfat->ffpfsc` instead.

💖 Sponsorship

MkPFS is easier to sustain when users who benefit from it help fund it.

<p>
<a href="https://github.com/sponsors/RenanGBarreto">
<img alt="GitHub Sponsors" src="https://img.shields.io/badge/Fund%20Development-GitHub%20Sponsors-e11d48?style=flat-square&logo=githubsponsors&logoColor=white" />
</a>
</p>

☕ Contributions

Other changes

* Fixed corrupted PFS images on large game folders caused by wrong inode mapping after flat_path_table collisions (43) RenanGBarreto
* fix: preflight PFSC temp spool space checks (34) Eamo5
* fix: clean PFSC spools after compression failures (38) Eamo5
* Skip compression for executables or files that are too small (33) RenanGBarreto
* fix(cli): default min-compress-size to resolved block size (32) RenanGBarreto
* Several performance improvements (30) RenanGBarreto
* Spool-free streaming `pack file` (`--no-spool`) with flat-memory verify/unpack/tree (19) rdmrocha

**Full Changelog**: https://github.com/PSBrew/MkPFS/compare/0.0.6...0.0.7

0.0.6

MkPFS is a command-line tool and Python library for building, verifying, inspecting, browsing, and extracting
PlayStation FileSystem (PFS) disk images. It works with common image naming conventions such as `.ffpfs`, `.ffpfsc`,
`.pfs`, `.dat`, and `.bin`, and fits both direct image workflows and PKG or FPKG inner-PFS generation.

🤖 What's Changed

- Several performance improvements
- Better windows compatibility
- Reduce memory usage
- Made the default flags and parameters compatible with ShadowMountPlus
- Fixed issues related to temporary directories
- And other minor fixes

🚀 Quick Start

bash
Install/Update using pip
python -m pip install -U "mkpfs"

Creating Images: Option 1: .exfat -> .ffpfsc (Works with ShadowMountPlus) (Maximum compatibility)
python -m mkpfs pack file './BREW1234.exfat' './BREW1234.exfat.ffpfsc'

Creating Images: Option 2: .ffpkg -> .ffpfsc (Works with ShadowMountPlus)
python -m mkpfs pack file './BREW1234.ffpkg' './BREW1234.ffpkg.ffpfsc'

Creating Images: Option 3: Game folder wrapped twice into .ffpfsc (two-pass) (Works with ShadowMountPlus)
python -m mkpfs pack folder --no-compress --no-adjust-output-file-extension './BREW1234-app' './pfs_image.dat'
python -m mkpfs pack file './pfs_image.dat' './BREW1234.ffpfsc'
rm './pfs_image.dat'

Creating Images: Option 4: Game folder without a wrapper (single-pass) (Experimental) (Works with ShadowMountPlus)
python -m mkpfs pack folder './BREW1234-app/' './BREW1234.ffpfsc'

Extracting Existing Images (Reverse operation)
python -m mkpfs unpack './BREW1234.ffpfs' './BREW1234-extracted/'


> **Note on conversion speed:** Antivirus scanning can reduce conversion speed, especially during the writing phase or when processing many loose files.
> If you plan to convert many titles in bulk and you trust this software in your environment, you may temporarily disable real-time antivirus protection to speed up the process.
> If you are unsure, keep antivirus enabled and expect slower conversions.

💖 Sponsorship

MkPFS is easier to sustain when users who benefit from it help fund it.

<p>
<a href="https://github.com/sponsors/RenanGBarreto">
<img alt="GitHub Sponsors" src="https://img.shields.io/badge/Fund%20Development-GitHub%20Sponsors-e11d48?style=flat-square&logo=githubsponsors&logoColor=white" />
</a>
</p>

☕ Contributions

* Several performance improvements (30) RenanGBarreto
* Spool-free streaming `pack file` (`--no-spool`) with flat-memory verify/unpack/tree (19) rdmrocha
* test(cli): assert help/output titles using dynamic version helpers (28) RenanGBarreto
* fix: fail-fast on non-ASCII filenames before compression starts (25) zyfcjtc
* Fix single-file staging fallback and gate game-file warnings in verify (24) [copilot-swe-agent[bot]](https://github.com/apps/copilot-swe-agent)
* Add README note about antivirus impact on conversion speed (20) [copilot-swe-agent[bot]](https://github.com/apps/copilot-swe-agent)
* Fix temp dir location for cross-drive hardlink failures on Windows (15) cherryduck

**Full Changelog**: https://github.com/PSBrew/MkPFS/compare/0.0.5...0.0.6

0.0.5

MAJOR BUG FIX

This relase solves a major issue present in versions 0.0.3 and 0.0.4. The files created by those versions were causing KP or not being loaded correctly due to an issue with the compression algorithm.


**Full Changelog**: https://github.com/PSBrew/MkPFS/compare/0.0.2...0.0.5

Page 1 of 2

© 2026 Safety CLI Cybersecurity Inc. All Rights Reserved.