@joewalker/scripture-ref
v0.6.0
Published
Manage references to Biblical passages
Downloads
414
Readme
scripture-ref
A TypeScript library for parsing, normalising, and looking up references to Biblical passages. The package handles the 66-book Western Christian canon and ships with the English Standard Version (ESV) text bundled as JSON, so consumers can resolve a parsed reference straight to its verse text without a network call.
The implementation is a port of JSword reduced to the parts an English-language web client typically needs.
Installation
The package is published to npm as @joewalker/scripture-ref:
Source and tagged releases are also available from the GitLab repository, and individual versions can be browsed on the releases page.
Quick start
import {
Passage,
esvTranslation as translation,
} from '@joewalker/scripture-ref';
const passage = Passage.fromString('John 3:16-17');
for (const { verse, text } of translation.getPassageText(passage)) {
console.log(`${verse.toString()} ${text}`);
}Formatting (joining verses, applying styles, choosing whether to inline verse numbers) is the consumer's responsibility. getPassageText returns the raw verse-by-verse data and stays out of presentation concerns.
search follows the same rule. It returns matching verses as structured data:
import { esvTranslation as translation } from '@joewalker/scripture-ref';
for (const { verse, text, score } of translation.search('Moriah')) {
console.log(`${verse.toString()} (${score}) -> ${text}`);
}API overview
The library is organised around three layers.
Verse, VerseRange, and Passage represent references at increasing levels of granularity. A Verse is a single book/chapter/verse triple. A VerseRange is a contiguous span of verses. A Passage is an unordered collection of one or more ranges, suitable for representing things like a daily reading or a topical lookup. PassageTally tracks scoring or ranking across verses, used for example by search.
Bible text is available through a Translation instance. The general API is const translation = await Translation.create('ESV');. Currently the only translation available is the ESV. There is an esvTranslation available as a shortcut.
translation.getPassageText(passage) is the bridge from a parsed reference to text. It returns a ReadonlyArray<VerseText> where each element is { verse, text }. search(bookId, terms) runs a keyword search across the bundled translation and returns a ReadonlyArray<SearchResult> where each element is { verse, text, score }. The score is the number of query terms matched in the verse; repeated occurrences of the same term in a verse do not add extra weight. The only bookId currently shipped is 'ESV'.
bible-info exposes structural helpers about the canon itself: findBookNumber, getShortName, getLongName, chaptersInBook, versesInChapter, versesInBible, chaptersInBible, booksInBible, verseOrdinal, decodeOrdinal, bookNames, and shortBookNames.
Project layout
src/
index.ts entry point and public exports
__testutil__/index.ts test-only re-exports (parser internals)
book/
books.ts getPassageText, search
data/*.json Bible translations (about 10MB per file)
passage/
bible-info.ts structural helpers
verse.ts Verse and parser
verse-range.ts VerseRange and parser
passage.ts Passage (multi-range)
passage-tally.ts PassageTally for rankingDevelopment
The relevant scripts are:
pnpm install # install dependencies
pnpm build # production build into dist/
pnpm tsc # compile all TypeScript, including tests
pnpm test # vitest, ~70 tests
pnpm lint # code safety checks
pnpm format # oxfmt
pnpm clean # remove build outputCI runs pnpm tsc, pnpm test, and pnpm lint on every pull request.
Version Control
Check-in tags
We use a set of tags at the start of commits to help us update the changelog (by enabling us to group commits and ignore inconsequential commits).
The following tags are ignored in the production of release notes.
Agent: Tweaks to the configuration of LLM agent config filesDocs: For updates to our documentation.Lint: For changes to satisfy lint/tsc/etc.Minor: Some small tweak like fixing a spelling mistake or changes to the editor configuration files.Refactor: For a change that makes the code nicer but doesn't introduce any new features.Release vX.X.X: When we push a release to production.Testing: For changes to the unit and integration tests.Upgrade: Keeping NPM dependencies up to date.Config: For changes to ci/pnpm/ts/git/etc. configuration files.
Example tags that would generally warrant a CHANGELOG.md entry:
Feature: Some new ability, which will typically result in a bumped minor release version number and potentially a callout in the the changelogFix: For a blatant bug fix. However when we're updating things as we go, we're more likely to use a tag for the ongoing work, so this is more for fixing longstanding bugs.Perf: Alterations to make things fasterSafety: For changes that make the system safer and easier to use.Security: For any fix that could be security sensitive.
Often there is a set of commits that achieve a larger goal and that work takes a tag.
License
Licensed under the Apache License, Version 2.0.
