Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

russian-nouns-js

georgy72.5kMIT2.3.0TypeScript support: definitely-typed

Declension by cases. Pluralization.

Russian, inflection, падежи, склонение-слов

readme

npm version MIT License


Logo

RussianNounsJS

A JavaScript library that declines nouns.

Test it in your browser · Report Bugs · Wiki


Installation

Frontend

<script src="RussianNouns.min.js"></script>

or (without AMD)

<!-- from the same domain -->
<script type="module" src="myscript.js"></script>
import 'RussianNouns.min.js';

or (in a Web Worker)

importScripts('RussianNouns.min.js');

Backend

npm i --save russian-nouns-js
const RussianNouns = require('russian-nouns-js');

Usage

The basics

const rne = new RussianNouns.Engine();

// Grammatical gender is a sort of noun class, related primarily to their sound.
// Although mostly native speakers just remember them.

const Gender = RussianNouns.Gender;
const Case = RussianNouns.Case;


rne.decline({text: 'имя', gender: Gender.NEUTER}, Case.GENITIVE);
// ◂ [ "имени" ]

rne.decline({text: 'имя', gender: Gender.NEUTER}, Case.INSTRUMENTAL);
// ◂ [ "именем" ]


// A number of loan words are not declined.
// You should explicitly state this to prevent inflection.

let coat = RussianNouns.createLemma({
    text: 'пальто',
    gender: Gender.NEUTER,
    indeclinable: true
});

rne.decline(coat, Case.GENITIVE);
// ◂ [ "пальто" ]

RussianNouns.getDeclension(coat);
// ◂ -1


// Cases can be specified not only by name, but also by number.
// In the usual order: NOM, GEN, DAT, ACC, INS, PREP.
// And there is also the locative case as the seventh.
// It usually matches the prepositional one.

let mountain = RussianNouns.createLemma({
    text: 'гора',
    gender: Gender.FEMININE
});

RussianNouns.CASES.map(c => {
    return rne.decline(mountain, c);
});

// ◂ [
//     ["гора"]
//     ["горы"]
//     ["горе"]
//     ["гору"]
//     ["горой", "горою"]
//     ["горе"],
//     ["горе"]
// ]


// This is how you can get a plural form in the nominative case.

rne.pluralize(mountain);
// ◂ [ "горы" ]


// When you have the plural form in the nominative case, pass it
// as the third argument of the decline function to decline in plural.

RussianNouns.CASES.map(c => {
    return rne.decline(mountain, c, 'горы');
});

// ◂ [ 
//     [ 'горы' ]
//     [ 'гор' ]
//     [ 'горам' ]
//     [ 'горы' ]
//     [ 'горами' ]
//     [ 'горах' ]
//     [ 'горах' ]
// ]


// For words that are used only in plural, the original form
// of the word is the plural form in the nominative case.
// You should also explicitly state this.
// The concept of grammatical gender doesn't make sense for such words.

let scissors = RussianNouns.createLemma({
    text: 'ножницы',
    pluraleTantum: true
});

rne.pluralize(scissors);
// ◂ [ 'ножницы' ]

RussianNouns.CASES.map(c => {
    return rne.decline(scissors, c);
});

// ◂ [
//     [ 'ножницы' ]
//     [ 'ножниц' ]
//     [ 'ножницам' ]
//     [ 'ножницы' ]
//     [ 'ножницами' ]
//     [ 'ножницах' ]
//     [ 'ножницах' ] 
// ]

A complex example

const Gender = RussianNouns.Gender;
const createLemma = RussianNouns.createLemma;

const rne = new RussianNouns.Engine();

function sg(lemma, caseNumber) {
    const c = RussianNouns.CASES[caseNumber - 1];
    return rne.decline(lemma, c)[0];
}

function pl(lemma, caseNumber) {
    const c = RussianNouns.CASES[caseNumber - 1];
    const pluralForm = rne.pluralize(lemma)[0];
    return rne.decline(lemma, c, pluralForm)[0];
}

function cap(str) {
    return str[0].toUpperCase() + str.substring(1);
}


// Николай Степанович Гумилев
// Рассказ девушки (фрагмент)

const ворота = createLemma({text: 'ворота', pluraleTantum: true});
const тень = createLemma({text: 'тень', gender: Gender.FEMININE});
const снег = createLemma({text: 'снег', gender: Gender.MASCULINE});

const милая = createLemma({text: 'милая', gender: Gender.FEMININE});
const старая = createLemma({text: 'старая', gender: Gender.FEMININE});
const ель = createLemma({text: 'ель', gender: Gender.FEMININE});

const неведомая = createLemma({text: 'неведомая', gender: Gender.FEMININE});
const высота = createLemma({text: 'высота', gender: Gender.FEMININE});

console.log(`* * *
Я отдыхала у ${pl(ворота, 2)}
Под ${sg(тень, 5)} ${sg(милая, 2)}, ${sg(старая, 2)} ${sg(ель, 2)},
А надо мною пламенели
${cap(pl(снег, 1))} ${pl(неведомая, 2)} ${pl(высота, 2)}.`);

// * * *
// Я отдыхала у ворот
// Под тенью милой, старой ели,
// А надо мною пламенели
// Снега неведомых высот.

Limitations

This library does not prevent you from misusing singularia tantum.

References

  • Современный русский язык. Морфология - Камынина А.А., Уч. пос. 1999 - 240 с.
  • Russian grammar (English Wikipedia)
  • OpenCorpora (Russian text corpus)
  • К семантике русского локатива ("второго предложного" падежа) - Плунгян В. А., Семиотика и информатика. - Вып. 37. - М., 2002. - С. 229-254

changelog

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

[2.3.0] - 2025-06-17

Added

  • Lemma.prototype.getDeclension
  • Lemma.prototype.getSchoolDeclension

Deprecated

  • RussianNouns.getDeclension
  • RussianNouns.getSchoolDeclension

Changed

  • Slight improvement in the declension of masculine possessive adjectives (not tested properly).

[2.2.0] - 2025-04-16

Changed

  • Improved declension of adjectives.

[2.1.0] - 2025-04-15

Fixed

  • Singular declension of 63 words.
  • Pluralization of 59 words.

[2.0.0] - 2025-04-07

Changed

  • The script works a little faster now, and the code is clearer in places, but it's bigger.

Deprecated

  • Lemma.prototype.newText
  • Lemma.prototype.newGender

Removed

  • pluraliaTantum named parameter
  • LemmaException (replaced by Error)
  • StressDictionaryException (replaced by Error)
  • RussianNouns.createLemmaNoThrow
  • RussianNouns.FIXED_STEM_STRESS public constant
  • RussianNouns.FIXED_ENDING_STRESS public constant
  • StressDictionary.putAll
  • StressDictionary.get
  • StressDictionary.remove
  • StressDictionary.find
  • Lemma.fuzzyEquals

[1.5.0] - 2025-03-30

Deprecated

  • pluraliaTantum named parameter (you should use pluraleTantum)
  • LemmaException (will be replaced by Error)
  • StressDictionaryException (will be replaced by Error)
  • RussianNouns.createLemmaNoThrow
  • RussianNouns.FIXED_STEM_STRESS public constant
  • RussianNouns.FIXED_ENDING_STRESS public constant
  • StressDictionary.putAll
  • StressDictionary.get
  • StressDictionary.remove
  • StressDictionary.find
  • Lemma.fuzzyEquals

Changed

  • Attributes in LocativeForm objects resulting from rne.getLocativeForms(lemma) are no longer an array, but bit flags. This feature is still experimental.

[1.4.2] - 2025-03-27

Fixed

  • I packed letters more tightly before hashing, which led to a smaller spread of values for short words. This eventually reduced the size of the script (minified and gzipped) by 245 bytes. To reduce the chance of collisions, I added a parity bit for the number of letters.

[1.4.1] - 2025-03-25

Added

  • RussianNouns.createLemmaOrNull. This is a method with minimal overhead.

Fixed

  • Bug in the stress dictionary, leading to ignoring whether words are animate.
  • Singular declension of 45 words, as well as pluralization of 29 words. It cost 202 bytes.

[1.4.0] - 2025-03-24

This is a fairly large refactoring, during which it was possible to increase the speed of passing tests by one and a half times. I simplified the internal representation of lemmas, moved some operations to the beginning of the script execution (see initializing the variables stemData, decline1Data, declinePluralData) and moved most of the stress dictionary to a hardcoded set of word hashes (for aesthetic reasons).

The size of the script (minified and gzipped) increased by 344 bytes.

[1.3.1] - 2021-11-13

Changed

  • A few lines in the default locative dictionary.

[1.3.0] - 2021-11-09

Added

  • New logo drawn by Alexander Elgin. This is black chokeberry. These are berries with an astringent flavor.
  • An experimental solution for the Issue #4: rne.getLocativeForms(lemma)

[1.2.5] - 2021-07-30

Added

  • RussianNouns.createLemmaNoThrow. This is a method with Go-like error handling.

Changed

  • Minor changes in Engine.decline.
  • Lemma constructor no longer validates arguments. It's not for external use anyway.