direction review
direction 2.0.1 answers one narrow question: is the first strong character in a string left-to-right, right-to-left, or absent? It returns `ltr`, `rtl`, or `neutral`. It does not run the Unicode Bidirectional Algorithm, count which script dominates, reorder glyphs, or shape Arabic. The current patch tightened the TypeScript signature and updated documentation. In our install it occupied 1 MB on disk, bundled to 0.4 KB minified, and brought no dependencies.
direction 2.0.1 installed in 0.3 seconds, added one 1 MB package, and produced a 0.3 KB gzipped browser bundle with 0 audit findings. Use it only when first-strong classification is the requirement; choose `dir=auto` or a bidi engine when rendering behavior is the requirement.
We installed it
| Install | ✓ · 0.3s | 1 package on disk · 1 MB |
| Import | ✓ | ESM import works · require() works · ESM package |
| Browser | 0.3 KB | gzipped (0.4 KB minified), bundled with esbuild |
| Types | ✓ | TypeScript types bundled |
| Known vulns | 0 | 0 critical · 0 high · 0 moderate · 0 low (npm audit) |
Answers from our run
Does direction install cleanly?
Yes. In a fresh container with an empty cache, npm install direction finished in 0.3s, leaving 1 package and 1 MB on disk. npm audit reported no known vulnerabilities.
How much does direction add to a browser bundle?
0.3 KB gzipped (0.4 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.
Does direction work with both ESM and CommonJS?
Yes. Both import 'direction' and require('direction') worked in Node 22 in our run. The package is published as ESM.
Does direction include TypeScript types?
Yes, type declarations ship inside the package, so no @types install is needed.
direction or bidi-js: which should you use?
bidi-js: Use it when JavaScript must apply Unicode bidi levels and reordering rather than return one base-direction label. direction 2.0.1 installed in 0.3 seconds, added one 1 MB package, and produced a 0.3 KB gzipped browser bundle with 0 audit findings.
When should you not use direction?
You need mixed Arabic, Hebrew, Latin, punctuation, and numbers rendered correctly. The README calls this a simple first-strong algorithm, not a bidi implementation.
Use it if
- You need a first-strong direction hint before assigning an HTML `dir` value or choosing text alignment.
- A three-value result is enough and mixed-direction reordering remains the browser or renderer's job.
- You want a typed function with no direct or peer dependencies for Node, Deno, or a modern browser.
- A shell script needs to classify one short argument or a small stdin chunk as `ltr`, `rtl`, or `neutral`.
- You need mixed Arabic, Hebrew, Latin, punctuation, and numbers rendered correctly. The README calls this a simple first-strong algorithm, not a bidi implementation.
- Most of the string should decide the result. `direction('Invoice فاتورة')` returns `ltr` because the first recognized letter wins.
- HTML already owns the decision. `dir=auto` asks the user agent to determine base direction without adding JavaScript.
- Your pipeline needs one answer after an entire large stdin stream. The CLI prints on each data chunk, so chunk boundaries can produce several lines.
- You require frequently refreshed Unicode tables. Version 2.0.1 was published in 2021, and the source keeps its character ranges in regular expressions.
Setup reality
We installed direction 2.0.1 in a fresh Node 22 Bookworm sandbox. npm completed in 0.3 seconds and left one package taking 1 MB on disk. The package is 28 KB unpacked, has 0 direct and 0 peer dependencies, includes TypeScript declarations, and uses the MIT license. npm audit reported 0 known vulnerabilities.
Package metadata marks version 2 as ESM and provides no exports map. Even so, both require() and ESM import worked in our Node 22 checks. Treat that CommonJS result as observed compatibility rather than the documented contract: the README calls the package ESM-only and shows the named import import {direction} from 'direction'.
The browser build measured 0.4 KB minified and 0.3 KB gzipped. No locale data or configuration file is involved. The function scans until it meets a recognized LTR or RTL character; empty strings, punctuation, digits, and emoji alone return neutral. It gives the same single label even when the remainder of the string uses another script.
The CLI joins command arguments with spaces. With no arguments it listens to stdin and writes a result for every incoming chunk, not once at end-of-file. For page content, assign the result to a container's dir property and keep text insertion safe with textContent; the package does not sanitize HTML or control visual reordering.
Patterns
Classify Latin text detect-ltr
import {direction} from 'direction';
const result = direction('Invoice 42');
console.log(result); // 'ltr'The first recognized Latin letter makes the result `ltr`; the digits do not affect it.
Classify Arabic text detect-rtl
import {direction} from 'direction';
const result = direction('فاتورة 42');
console.log(result); // 'rtl'The result is a base-direction hint. Arabic shaping and visual order remain the renderer's work.
Recognize strings without strong characters handle-neutral
import {direction} from 'direction';
for (const text of ['', '123', '@', '🙂']) {
console.log(direction(text)); // 'neutral'
}Digits, punctuation, emoji, and an empty string do not match the package's LTR or RTL ranges.
See the first-strong rule inspect-mixed-text
import {direction} from 'direction';
console.log(direction('Invoice فاتورة')); // 'ltr'
console.log(direction('فاتورة Invoice')); // 'rtl'Reversing the leading script reverses the answer even though both strings contain the same two words.
Assign a direction to an element set-element-direction
import {direction} from 'direction';
const message = 'مرحبا';
const node = document.createElement('p');
node.dir = direction(message);
node.textContent = message;Use `textContent` for untrusted input. This package classifies text and does not sanitize HTML.
Choose a product-specific neutral default fallback-neutral
import {direction} from 'direction';
function layoutDirection(text) {
const value = direction(text);
return value === 'neutral' ? 'ltr' : value;
}The library deliberately returns `neutral`; your surrounding language or layout policy must choose the fallback.
Let HTML classify editable content prefer-browser-auto
const input = document.createElement('textarea');
input.dir = 'auto';`dir=auto` lets the browser recalculate base direction as content changes and requires no package import.
Classify one command-line value classify-cli-argument
npx direction 'שלום עולם'
# rtlCommand arguments are joined with spaces before classification. Put `--` before text that begins with a command option marker.
Pipe a short string through the CLI classify-stdin
printf '%s' 'English text' | npx direction
# ltrThe CLI emits once per stdin data chunk, so a long or slowly produced stream may print more than one result.
Use the literal return union type-return-value
import {direction} from 'direction';
type Direction = ReturnType<typeof direction>;
const value: Direction = direction(userText);The bundled declaration narrows the result to `'ltr' | 'rtl' | 'neutral'`, which supports exhaustive branching.
Handle every result explicitly switch-direction
const value = direction(text);
switch (value) {
case 'rtl': alignRight(); break;
case 'ltr': alignLeft(); break;
case 'neutral': inheritAlignment(); break;
}Keeping `neutral` separate avoids silently treating punctuation-only content as Latin text.
Load from CommonJS on tested Node import-commonjs-observed
const { direction } = require('direction');
console.log(direction('hello'));`require()` worked in our Node 22 sandbox, but the README documents version 2 as ESM-only. Prefer the named ESM import for portable support.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| bidi-js | npm | Use it when JavaScript must apply Unicode bidi levels and reordering rather than return one base-direction label. |
| rtl-detect | npm | Use it when a known language code or locale should determine whether the interface is normally RTL. |
| unicode-bidiclass | npm | Use it when you need the Unicode bidirectional class for individual code points as a lower-level primitive. |
More utils guides
lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →
How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.

