Batch-fix EPUBs that fail on Kobo/Adobe RMSDK due to unsupported CSS3+ features
Project description
epubfix
Batch-fix EPUBs that silently fail on Kobo (and Adobe Digital Editions) due to unsupported CSS3+.
The Problem
Kobo e-readers use Adobe's RMSDK engine — a CSS parser frozen circa 2013. When your EPUB contains modern CSS (flexbox, grid, min(), custom properties, etc.), Kobo doesn't give you an error. It just says the file is "corrupted" and refuses to open it.
This happens even when your EPUB passes epubcheck perfectly.
See: "Your EPUB Is Fine. Kobo Disagrees. Blame Adobe."
What epubfix does
Scans all CSS in an EPUB (external .css files, inline <style> blocks, style="" attributes) and replaces unsupported values with safe fallbacks:
| Broken CSS | Smart Fallback |
|---|---|
max-width: min(150px, 30vw) |
max-width: 150px |
font-size: clamp(1rem, 2vw, 2rem) |
font-size: 2vw |
color: var(--main-color, #333) |
color: #333 |
display: flex |
display: block |
display: grid |
display: block |
aspect-ratio: 2/3 |
(removed — no safe equivalent) |
94% of CSS retained on real-world EPUBs while removing all RMSDK-breaking features.
Install
pip install epubfix
Requires Python 3.11+ and one dependency (ebooklib).
Usage
# Fix a single EPUB
epubfix book.epub
# Output: book_fixed.epub
# Custom output path
epubfix book.epub -o book-kobo.epub
# Batch fix all EPUBs in a folder
epubfix --batch /path/to/epubs/
# Check for issues without fixing
epubfix --check book.epub
# Verbose output
epubfix book.epub -v
# JSON output (for scripting/CI)
epubfix book.epub --json
What gets fixed
| Feature | Action |
|---|---|
min(), max(), clamp() |
Replaced with safe fallback value |
var(--name, fallback) |
Replaced with fallback |
display: flex/grid |
Replaced with display: block |
| Flexbox/grid sub-properties | Removed |
Modern selectors (:is, :where, :has) |
Entire rule removed |
Modern colors (oklch, color-mix) |
Removed |
| Transitions/animations/transforms | Removed |
aspect-ratio, object-fit |
Removed or safe default |
Custom properties (--var) |
Removed |
Tested on the Blitz EPUB CSS framework (1,194 lines of modern CSS) and W3C EPUB 3 test suite — all RMSDK-unsafe CSS eliminated.
How it works
- Opens the EPUB as a ZIP archive via ebooklib
- Finds all CSS files and inline
<style>blocks - Replaces unsupported values with safe fallbacks
- Rebuilds the EPUB with clean CSS
- Original file is never modified
Compared to other tools
| epubfix | kobofix | |
|---|---|---|
| Install | pip install epubfix |
Single .py file, no deps |
| Batch mode | ✅ Built-in | ❌ |
| CSS fallbacks | Smart (preserves values) | Smart (more granular) |
| Web app | ❌ | ✅ (drag-and-drop) |
| EPUBCheck integration | ❌ | ✅ |
rem → px |
❌ | ✅ |
vw/vh → px |
❌ | ✅ |
| Zero dependencies | ❌ (ebooklib) | ✅ |
Use kobofix if you want a no-install tool with EPUBCheck integration and viewport unit conversion. Use epubfix if you want pip install, batch processing, or programmatic access.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file epubfix-0.2.0.tar.gz.
File metadata
- Download URL: epubfix-0.2.0.tar.gz
- Upload date:
- Size: 201.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f3effe6e18549e7538ec470597ee669b0504926cda0dd3d1852c338a8029b3b
|
|
| MD5 |
74a38f98b75fb31d0108abaaa9aba1bc
|
|
| BLAKE2b-256 |
f9ed76967a31222857bd57484fcec68cbef5b207137008c11b27908ad007ce96
|
File details
Details for the file epubfix-0.2.0-py3-none-any.whl.
File metadata
- Download URL: epubfix-0.2.0-py3-none-any.whl
- Upload date:
- Size: 10.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b444111bf89b08b7e4b761bb0b37b0f2230bc57ce701ba1c9b9c14b1d99c306
|
|
| MD5 |
bb770114bfa869c6a2782a73522f972b
|
|
| BLAKE2b-256 |
cc5ffccff4b29f435c92eb8863c2dc93a4017fdf4708496e92b517a450941e36
|