# comimi mounts a manga viewer into one element and declares no dependencies

> A TypeScript comic reader published as an ESM-only npm package whose package.json lists no runtime dependencies and no peer dependencies at all, which is the mechanical reason it can claim to work outside React. The API is a single factory function, and everything past the minimum example lives in a usage document the README does not summarise.

**yui540/comimi** — Open-source comic reader library for JS/TS

- Repository: https://github.com/yui540/comimi
- Website: https://yui540.com/comimi
- Stars: 470 · Forks: 20
- Language: TypeScript
- License: MIT
- Published: 2026-09-20 · Updated: 2026-09-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/yui540-comimi

## One factory function, one element, and a manga object

The entire public surface in the README is one call. You import `createMangaViewer`, hand it a DOM element and a configuration object, and it mounts itself:

```ts
import { createMangaViewer } from "@yui540/comimi";

createMangaViewer(document.querySelector("#viewer")!, {
  manga: {
    id: "sample",
    title: "サンプル漫画",
    author: "yui540",
    pages: [
      { id: "p0", type: "image", src: "/pages/0.webp" },
      { id: "p1", type: "image", src: "/pages/1.webp" },
      { id: "p2", type: "image", src: "/pages/2.webp" },
    ],
  },
});
```

Three things in that shape are decisions rather than convenience. The first argument is an element you already have, so the library mounts into your page rather than creating a container of its own. The configuration is one nested object, a manga with an identifier, a title, an author and a page array, rather than a flat list of options. And the return value is a handle: the README says page turning, settings and event operations all go through the returned instance, so the DOM is managed for you but not hidden from you.

One field deserves a note. Each page carries a `type`, and the example only ever sets it to `image`. A schema with a type discriminator and one documented value implies there are others, and the README does not enumerate them, which is exactly the kind of question the usage document exists to answer.

## No dependencies and no peerDependencies, which is the whole claim

The README says the library does not depend on UI libraries such as React and therefore works standalone. That statement has a mechanical basis, and it is worth checking rather than taking on trust.

The `package.json` contains no `dependencies` block and no `peerDependencies` block. There is nothing to install alongside it and nothing for your framework to satisfy. All three entries are dev dependencies: Vite, TypeScript and the basic SSL plugin for Vite. So the claim is not that React is optional, it is that React is absent, along with everything else a viewer of this kind would normally reach for.

That has a second consequence that the README does not mention. The package sets `type` to `module`, and the `exports` map for the root entry offers `types` and `import`, with no `require` condition. A CommonJS consumer therefore cannot `require` this package, even though the legacy `main` field points at the same built file. From CommonJS the options are a dynamic import or a bundler that resolves ESM, and if your build pipeline is still CommonJS that is the first thing that will stop working.

## The build typechecks twice with two different tsconfig files

The build script is a three-step chain rather than one bundler invocation:

```bash
npm run dev            # examples/preview を開発サーバーで起動
npm run build          # ライブラリ本体を dist/ にビルド
npm run build:preview  # examples/preview を静的サイトとして dist-preview/ にビルド
```

The `build` script runs `tsc --noEmit` first, then `vite build`, then `tsc -p tsconfig.build.json`. So the type errors are caught before anything is emitted, the bundle is produced by Vite, and the declaration files are generated in a separate pass with a different configuration file. There are two `tsconfig` files at the root for that reason, one for checking and one for emitting.

A detail worth knowing if you fork it: all three dev dependencies are pinned to the string `latest` rather than to a version range. Nothing in the published package depends on them, so consumers are unaffected, but a contributor cloning today and a contributor cloning next month may be on different toolchains. `prepublishOnly` runs the build, so a bad type error blocks publishing rather than shipping.

The preview output is a static site in `dist-preview/`, and the README says it can be dropped onto static hosting such as Cloudflare Pages as-is, naming the build command and the output directory.

## The preview server runs over HTTPS and binds every interface

The dev and preview scripts both pass `--host 0.0.0.0` to Vite, and the dev dependency list includes a basic SSL plugin for Vite. Together those two facts mean the preview server is reachable from other machines on your network and is served over HTTPS rather than plain HTTP.

Binding `0.0.0.0` in a dev script is a common convenience, since it lets you open the preview on a phone to check a comic reader's touch behaviour. It is also a development server with no authentication, and there are two Vite configuration files at the root, `vite.config.ts` and `vite.preview.config.ts`, so the library build and the preview build are configured independently.

The preview itself lives under `examples/preview/`, which is the only example directory in the repository, and the dev script is pointed at its configuration file rather than at the library. That separation is the right structure for a package whose deliverable is a library: the example is a consumer, and it will break the same way your page would.

## locales/ and docs/ ship in the tarball, and neither is summarised in the README

The published `files` array lists three things: `dist`, `locales` and `docs`. Translation resources are therefore a first-class part of the package rather than something the host page supplies, and the documentation travels with the code.

The README confirms the first point by implication and the second by omission. It says the API details, options, settings, keyboard shortcuts, persistence and i18n are all described in `docs/USAGE.md`. So six areas of behaviour are named and none of them is explained where you are reading.

That is a reasonable split for a project this size, since a usage document that tried to fit in a README would be a worse document. It does mean the evaluation you want to make cannot be made from the front page. Before adopting, the question to answer is not whether the viewer mounts, which the README proves, but whether the options list in the usage document covers the behaviour you need, and the repository does not summarise that list anywhere in the visible text.

## Version 0.26.0 on npm, with nothing on GitHub to compare it to

The package version is 0.26.0 and the repository has no GitHub releases. So the npm version is the only version handle there is, and the number itself says the library is pre-1.0, where breaking changes are expected under the usual convention rather than being treated as a defect.

The package is scoped, `@yui540/comimi`, and published with public access. Its keywords are manga, comic, viewer, reader and typescript, which is a fair description of a library whose job is to make a comic readable on a page.

The project also has a site at `yui540.com/comimi`, and the README carries a short video asset linked from the repository. Licence is MIT, and the last push to the repository was 2026-09-16.

What is absent from the repository is as informative as what is present. There is no test directory, no changelog, no contributing file and no CI configuration at the root, which for a project shipping a DOM-managing library to other people's pages is worth asking about before you depend on it.

## The trade is DOM ownership instead of composition

The nearest alternative is the obvious one: a manga viewer written as a React or Vue component, which is what most comic readers on the web are. The difference in approach is not quality, it is who owns the subtree.

A component receives props and renders inside your tree, so your styles, your layout and your state management apply to it directly. comimi takes an element and manages the DOM inside it, which means you get a self-contained reader with no framework requirement and no dependency to install, and you give up the ability to compose it out of your own components or to style its internals with your own utility classes unless the options object exposes a way to do so.

That is a good trade on a content page and a bad one inside a design system. The documentation lists settings as something you operate through the returned instance, which suggests configuration rather than styling hooks, so for a site with an existing visual language the question to put to the usage document is how appearance is set. Nothing in the visible text answers it, and that is the honest limit of what this repository shows.

## Conclusion

Adopt comimi if you want a comic reader on a site that has no UI framework, because a library with no dependencies and one mount point is the right shape for a static page and for a content site you do not control. Do not adopt it if your application is already React-based and you want a component, since this package owns the DOM subtree it renders into and offers no composition point. Verify three things before you commit: that the options and event surface in `docs/USAGE.md` covers what you need, because the README documents only the minimum example, that your bundler resolves an ESM-only package, since there is no `require` condition in the exports map, and whether the `type` field on a page accepts anything beyond `image`, which the example never demonstrates. The current version is 0.26.0, the last push was 2026-09-16, and the licence is MIT.

## FAQ

### What is comimi?

It is an open-source comic reader library for JavaScript and TypeScript, published as `@yui540/comimi`. You mount it into a DOM element you provide and it manages that subtree itself, with no dependency on React or any other UI library.

### How do I install and mount comimi?

Run `npm install @yui540/comimi`, then call `createMangaViewer` with an element and a manga object holding an id, title, author and page array. The viewer mounts into that element, manages the DOM, and returns an instance through which you do page turning, settings and event operations.

### Does comimi depend on React or any framework?

No. The package.json lists no dependencies and no peerDependencies at all, and the three dev dependencies are Vite, TypeScript and a Vite SSL plugin. The README states it runs standalone because it does not depend on UI libraries such as React.

### Can I use comimi from CommonJS?

Not with `require`. The package sets `type` to `module` and its exports map offers a `types` and an `import` condition with no `require` condition, so a CommonJS project needs a dynamic import or a bundler that resolves ESM.

### What does the comimi npm package ship?

Three directories, `dist`, `locales` and `docs`. Translations are part of the package rather than something the host page supplies, and the usage document covering the API, options, settings, keyboard shortcuts, persistence and i18n travels with it.

### What version of comimi is current?

0.26.0 on npm, and the repository has no GitHub releases, so the package version is the only version handle. The last push was 2026-09-16 and the licence is MIT.

## Sources

- [Issues](https://github.com/yui540/comimi/issues)
- [License: MIT](https://github.com/yui540/comimi/blob/main/LICENSE)
- [Project website](https://yui540.com/comimi)
- [README](https://github.com/yui540/comimi/blob/main/README.md)
- [yui540/comimi on GitHub](https://github.com/yui540/comimi)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/yui540-comimi
