npm package
tate-chu-yoko
A small library that automatically wraps half-width alphanumerics inside vertical Japanese text so CSS `text-combine-upright` can compose them as tate-chu-yoko (縦中横). Authors write plain text; typesetting is handled for them.
第1章 2026年4月、Webの縦書きは進化した。
What it solves
Japanese vertical writing (writing-mode: vertical-rl) leaves half-width Latin letters and digits lying on their side. The fix — text-combine-upright: all — exists, but the developer still has to decide *which* runs to apply it to, usually by wrapping them in <span class="tcy"> by hand. That chore leaks into manuscripts, CMSes, and Markdown. tate-chu-yoko does the wrapping for you, so authors can keep writing plain text.
Five packages
At the center is @love-rox/tcy-core, a framework-agnostic tokenizer. Pick whichever adapter (or adapters) suits your stack — core is pulled in automatically as a dependency.
Adapters
@love-rox/tcy-react
React component
A <Tcy> component for React 17+ that produces deterministic SSR-safe DOM.
@love-rox/tcy-vue
Vue 3 component
The same <Tcy> API for Vue 3 — identical options and behavior.
@love-rox/tcy-rehype
rehype plugin
Slots into a unified HAST pipeline so the wrapping happens at build time. No client runtime required.
@love-rox/tcy-astro
NEWAstro integration + component
Registers the rehype plugin on Astro 4+'s Markdown / MDX pipeline, and ships a <Tcy> component for .astro files.
One CSS rule everywhere
No matter which adapter you choose, the generated <span class="tcy"> elements need the same CSS. Including -webkit-text-combine keeps Safari happy.
.tcy {
-webkit-text-combine: horizontal;
text-combine-upright: all;
}What's true across the board
- Runs are not joined across element boundaries —
<em>12</em>34produces two separate spans. - Full-width alphanumerics (
A–Z/0–9) are left alone because they already render upright in vertical text. - React, Vue, and the Astro
<Tcy>are SSR-safe: server and client emit the same DOM. - The rehype plugin (and the Astro integration that wraps it) is idempotent — running it twice on the same HAST gives the same output as running it once.
- Runs filtered out by
maxLengthorexcludeWordsare demoted back to plain text and merged into the surrounding text segment automatically.
Browser support
writing-mode: vertical-rl and text-combine-upright: all are supported in all modern browsers. For Safari it's still worth including -webkit-text-combine: horizontal alongside the standard property.
Shared version line
All five packages release on the same shared version line, anchored to @love-rox/tcy-core. Whenever any one of them changes, the others move to the same number — so you never have to wonder whether react@0.2.5 is compatible with core@0.3.0.
License
MIT License. Free to use in personal and commercial projects.
See it in action
The interactive demo lets you tweak options and compare the raw text with the <Tcy> output side by side.