Open-source project
dteviot/WebToEpub avatar
dteviot/WebToEpub

WebToEpub: turning serialised web novels into EPUB files

A simple Chrome (and Firefox) Extension that converts Web Novels (and other web pages) into an EPUB.

1,507 stars314 forksJavaScriptNOASSERTION

At a glance

What is it?
WebToEpub is a Chrome and Firefox extension that converts a web novel, or almost any other web page, into an EPUB for offline reading, with a parser written for each supported site and a generic path for sites that have none. It is a JavaScript project that has been shipping since 2015, and its default branch is named ExperimentalTabMode.
Who is it for?
Adopt WebToEpub if you read serialised fiction on sites that have no proper reader, or you follow translations that post one chapter at a time, and you want an EPUB on your own device rather than a reading page. Do not adopt it for content you have no right to copy, since the extension makes downloading a one-click operation and the responsibility for that is yours.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 13 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A download button for chapter-by-chapter fiction

WebToEpub is a browser extension for Firefox and Chrome that converts web novels and other web pages into EPUB format, for offline reading. The problem it solves is specific to how serialised fiction is published online. A novel posted one chapter at a time is technically a set of HTML pages, and reading it offline or on an e-reader means either saving each page by hand or using the site's own reader, which is often a heavier web page than the text needs. The extension walks the chapters, collects them, and produces a single EPUB file that a reader application can open. The project dates from 2015 and credits David Teviotdale as the author, and the description of the tool is deliberately modest, a simple Chrome and Firefox extension. That framing matters for expectations: this is a utility for one narrow job, not a reading platform, and the whole design follows from that.

One parser per site, and a generic path when there is none

The extension's intelligence is a set of site parsers, and the size of that set is the project's real work. The supported list runs to hundreds of domains, covering translation sites, aggregator sites and the big fan fiction hosts, with names like baka-tsuki.org, archiveofourown.org, fanfiction.net, wuxiaworld.com and royalroad.com among the ones named in the project description, and a long tail beyond that including many novel aggregators, Chinese-language sites and personal translation blogs. The documentation in the README has separate sections for using it with Baka-Tsuki, using it with Archive of Our Own, using it for a site that has no specific parser, and creating parsers for new sites, which tells you how the extension is meant to scale: a site with a bespoke parser gets a clean result, and a site without one still works through the generic path, at the cost of a possibly messy extraction. A site can also change its layout, which is why the issue tracker has a dedicated add-site request template alongside bug report and feature request templates.

The extension shell, and how the build assembles it

The repository is small and the layout says what the project is. There is a plugin/ directory holding the extension itself, with popup.html as the entrypoint named in package.json, a unitTest/ directory for the tests, testdata/ for fixtures, doc/ for documentation, an eslint/ directory that contains its own build tooling, and package.json at the root. The runtime dependencies are two: @zip.js/zip.js for producing the EPUB container and dompurify for sanitising the scraped HTML before it goes into the file. The dev dependencies are the toolchain, including @xmldom/xmldom for DOM handling in tests, copyfiles, eslint, http-server and web-ext. The postinstall step copies the two vendored browser bundles into the plugin directory, pulling in zip-no-worker.min.js from the zip library and purify.min.js from dompurify, which is what lets the extension work without a bundler at runtime.

The npm scripts are the developer workflow

Everything the project does in development is expressed as npm scripts, and they are worth reading because they show the shape of the build. The up script is npm install, which is what a contributor runs first. The test script starts a local web server and opens the test page in a browser:

bash
"test": "http-server -o unitTest/Tests.html"

That is a browser-based test suite rather than a headless one, which fits a project whose unit of work is DOM manipulation. The lint script first builds the eslint directory and then lints the resulting files:

bash
"lint": "cd eslint && node pack.js && eslint *.js"

and the build script is the first half of that, `cd eslint && node pack.js`, which produces the packed extension. The web-ext script lints the built package with Mozilla's extension validator, and the release script runs node eslint/release.js. The web-ext dependency is a Mozilla tool, which fits the fact that the extension targets both browsers from one codebase.

The default branch is called ExperimentalTabMode

One detail in the repository metadata deserves attention because it will confuse anyone who clones without reading. The default branch is named ExperimentalTabMode, not master or main. The project also publishes two kinds of release: numbered ones such as 1.0.13.0 and 1.0.14.0, and a developer-build tag that tracks the newest commit, with the developer build dated 2026-10-10 and the last push on the same day. The experimental tab mode is therefore a feature branch that happens to be the branch head, which means the code you get by default may include an unfinished interface experiment, while the numbered releases are the versions a user should install from the Firefox Add-ons listing or the Chrome Web Store. The README's table of contents lists installation routes for both browsers, from the store and from source, plus a separate section for Android that is marked untested. That is the second thing to know: the extension is not supported on Android Firefox, and the from-source routes are for contributors, not users.

The licence question is not as simple as the badge

The README carries a GPLv3 license shield pointing at the LICENSE file, and that badge names GPLv3. The repository metadata, however, classifies the licence as Other, meaning a custom licence that GitHub cannot categorise. The repository root carries a LICENSE.md file, and the README has its own License section, so the authoritative text is in the file rather than in the badge. That combination is worth pausing on for anyone shipping the extension inside a larger product, since the difference between a recognisable licence and an unclassifiable one is exactly the kind of thing a legal review will ask about. The practical read for a user is different and simple: the extension is free to install and use from the Firefox Add-ons listing and the Chrome Web Store, and the code of conduct and contribution links are in the same README.

Editorial conclusion

Adopt WebToEpub if you read serialised fiction on sites that have no proper reader, or you follow translations that post one chapter at a time, and you want an EPUB on your own device rather than a reading page. Do not adopt it for content you have no right to copy, since the extension makes downloading a one-click operation and the responsibility for that is yours. Before you rely on it, check whether your site is on the supported list or whether the generic parser handles its layout, confirm the EPUB opens in your reader, and read the LICENSE.md file, because the project carries a GPLv3 badge while GitHub classifies the licence as a custom one.

Frequently asked questions

What does WebToEpub do?

It is a browser extension for Firefox and Chrome that converts web novels and other web pages into EPUB format for offline reading. Its package.json description calls it an extension that converts a story on Baka-Tsuki or a number of other sites into an EPUB.

What happens if my site is not on the supported list?

The documentation has a section on using it for a site that has no specific parser, and a separate section on creating parsers for new sites, so the generic path still works and a bespoke parser can be contributed.

How do I run the tests for WebToEpub?

The test script in package.json is `http-server -o unitTest/Tests.html`, which serves the unitTest directory and opens the test page in a browser. The test suite is browser-based rather than headless.

Is WebToEpub available on Android?

The README's table of contents lists an Android section marked untested, so the extension is not a supported route there. The supported installs are from Firefox Add-ons, the Chrome Web Store, or from source for contributors.

What licence is WebToEpub released under?

The README carries a GPLv3 license shield and the repository carries a LICENSE.md file, but GitHub classifies the licence as a custom one it cannot categorise. The last push was on 2026-10-10, and the current numbered release is 1.0.14.0.

Official sources

  1. dteviot/WebToEpub on GitHub
  2. Issues
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dteviot-webtoepub.svg)](https://hysenlabs.com/projects/dteviot-webtoepub)

Was this useful?