Parse and compile gettext po and mo files, nothing more, nothing less
JavaScript
170
213 commits
updated Sep 29, 2026
Parse and compile gettext po and mo files with node.js, nothing more, nothing less.
Please note: starting with version 3 only latest LTS and latest stable node versions are supported. Use version 2 with older node versions.
Include the library:
import gettextParser from "gettext-parser";
Parse a PO file with
gettextParser.po.parse(input[, options]) → Object
Where
defaultCharset is the charset to use if charset is not defined or is the default "CHARSET" (applies only if input is a Buffer)
validation is a flag to turn on PO source file validation. The validation makes sure that:
msgid_plural definition per translation entry; a Multiple msgid_plural error error gets thrown otherwise.msgid values; a Duplicate msgid error error gets thrown otherwise.nplurals defined in Plural-Forms header for entries that have plural forms; a Plural forms range error error gets thrown otherwise.msgstr matches exacty the one (if msgid_plural is not defined) or the number from nplurals (if msgid_plural is defined); a Translation string range error error gets thrown otherwise.\n (matching GNU gettext, which rejects strings spanning multiple lines); an End-of-line within string error gets thrown otherwise.End-of-file within string error gets thrown otherwise.Method returns gettext-parser specific translation object (see below)
Example
import { readFileSync } from 'node:fs';
var input = readFileSync('en.po');
var po = gettextParser.po.parse(input);
console.log(po.translations['']); // output translations for the default context
PO files can also be parsed from a stream source. After all input is processed the parser emits a single 'data' event which contains the parsed translation object.
gettextParser.po.createParseStream([options][, transformOptions]) → Transform Stream
Where
parse. See Parse PO files section for details.Example
import { createReadStream } from 'node:fs';
var input = createReadStream('en.po');
var po = gettextParser.po.createParseStream();
input.pipe(po);
po.on('data', function(data){
console.log(data.translations['']); // output translations for the default context
});
If you have a translation object you can convert this to a valid PO file with
gettextParser.po.compile(data[, options]) → Buffer
Where
false) if true, entries will be sorted by msgid in the resulting .po(.pot) file.
If a comparator function is provided, that function will be used to sort entries in the output. The function is called with two arguments, each of which is a single message entry with the structure described below. The function should follow the standard rules for functions passed to Array.sort(): return 0 if the entries are interchangeable in sort order; return a number less than 0 if the first entry should come before the second one; and return a number greater than 0 if the second entry should come before the first one.true) if false, will skip escape newlines and quotes characters functionality.Example
import { writeFileSync } from 'node:fs';
var data = {
...
};
var output = gettextParser.po.compile(data);
writeFileSync('filename.po', output);
Parse a MO file with
gettextParser.mo.parse(input[, defaultCharset]) → Object
Where
"CHARSET"Method returns gettext-parser specific translation object (see below)
Example
import { readFileSync } from 'node:fs';
var input = readFileSync('en.mo');
var mo = gettextParser.mo.parse(input);
console.log(mo.translations['']); // output translations for the default context
If you have a translation object you can convert this to a valid MO file with
gettextParser.mo.compile(data) → Buffer
Where
Example
import { writeFileSync } from 'node:fs';
var data = {
...
};
var output = gettextParser.mo.compile(data);
writeFileSync('filename.mo', output);
If you are compiling a previously parsed translation object, you can override the output charset with the charset property (applies both for compiling mo and po files).
var obj = gettextParser.po.parse(inputBuf);
obj.charset = "windows-1257";
outputBuf = gettextParser.po.compile(obj);
Headers for the output are modified to match the updated charset.
By default gettext-parser uses pure JS iconv-lite for encoding and decoding non UTF-8 charsets. If you need to support more complex encodings that are not supported by iconv-lite, you need to add iconv as an additional dependency for your project (gettext-parser will detect if it is available and tries to use it instead of iconv-lite).
Parsed data is always in unicode but the original charset of the file can
be found from the charset property. This value is also used when compiling translations
to a mo or po file.
Headers can be found from the headers object and the value for a key is a string. This value will also be used when compiling.
Key casing isn't lowercased: the ~10 standard gettext headers (Language, Plural-Forms, Content-Type, ...) are recognized case-insensitively and normalized to their canonical name, while any other header (e.g. a tool-specific X-Poedit-* header) keeps whatever casing the source file used, unchanged (see #52).
Translations can be found from the translations object which in turn holds context objects for msgctxt. Default context can be found from translations[""].
Context objects include all the translations, where msgid value is the key. The value is an object with the following possible properties:
translator, reference, extracted, flag, previous.Example
{
"charset": "iso-8859-1",
"headers": {
"content-type": "text/plain; charset=iso-8859-1",
"plural-forms": "nplurals=2; plural=(n!=1);"
},
"translations": {
"": {
"": {
"msgid": "",
"msgstr": ["Content-Type: text/plain; charset=iso-8859-1\n..."]
}
},
"another context": {
"%s example": {
"msgctxt": "another context",
"msgid": "%s example",
"msgid_plural": "%s examples",
"msgstr": ["% näide", "%s näidet"],
"comments": {
"translator": "This is regular comment",
"reference": "/path/to/file:123"
}
}
}
}
}
Notice that the structure has both a headers object and a "" translation with the header string. When compiling the structure to a mo or a po file, the headers object is used to define the header. Header string in the "" translation is just for reference (includes the original unmodified data) but will not be used when compiling. So if you need to add or alter header values, use only the headers object.
If you need to convert gettext-parser formatted translation object to something else, eg. for jed, check out po2json.
MIT
Overall
Maintained
Code review
Latest release
Releases this year
410 followers · starred Dec 2022
60 followers · starred Oct 2022
Parse and compile gettext po and mo files, nothing more, nothing less
JavaScript
170
213 commits
updated Sep 29, 2026
Parse and compile gettext po and mo files with node.js, nothing more, nothing less.
Please note: starting with version 3 only latest LTS and latest stable node versions are supported. Use version 2 with older node versions.
Include the library:
import gettextParser from "gettext-parser";
Parse a PO file with
gettextParser.po.parse(input[, options]) → Object
Where
defaultCharset is the charset to use if charset is not defined or is the default "CHARSET" (applies only if input is a Buffer)
validation is a flag to turn on PO source file validation. The validation makes sure that:
msgid_plural definition per translation entry; a Multiple msgid_plural error error gets thrown otherwise.msgid values; a Duplicate msgid error error gets thrown otherwise.nplurals defined in Plural-Forms header for entries that have plural forms; a Plural forms range error error gets thrown otherwise.msgstr matches exacty the one (if msgid_plural is not defined) or the number from nplurals (if msgid_plural is defined); a Translation string range error error gets thrown otherwise.\n (matching GNU gettext, which rejects strings spanning multiple lines); an End-of-line within string error gets thrown otherwise.End-of-file within string error gets thrown otherwise.Method returns gettext-parser specific translation object (see below)
Example
import { readFileSync } from 'node:fs';
var input = readFileSync('en.po');
var po = gettextParser.po.parse(input);
console.log(po.translations['']); // output translations for the default context
PO files can also be parsed from a stream source. After all input is processed the parser emits a single 'data' event which contains the parsed translation object.
gettextParser.po.createParseStream([options][, transformOptions]) → Transform Stream
Where
parse. See Parse PO files section for details.Example
import { createReadStream } from 'node:fs';
var input = createReadStream('en.po');
var po = gettextParser.po.createParseStream();
input.pipe(po);
po.on('data', function(data){
console.log(data.translations['']); // output translations for the default context
});
If you have a translation object you can convert this to a valid PO file with
gettextParser.po.compile(data[, options]) → Buffer
Where
false) if true, entries will be sorted by msgid in the resulting .po(.pot) file.
If a comparator function is provided, that function will be used to sort entries in the output. The function is called with two arguments, each of which is a single message entry with the structure described below. The function should follow the standard rules for functions passed to Array.sort(): return 0 if the entries are interchangeable in sort order; return a number less than 0 if the first entry should come before the second one; and return a number greater than 0 if the second entry should come before the first one.true) if false, will skip escape newlines and quotes characters functionality.Example
import { writeFileSync } from 'node:fs';
var data = {
...
};
var output = gettextParser.po.compile(data);
writeFileSync('filename.po', output);
Parse a MO file with
gettextParser.mo.parse(input[, defaultCharset]) → Object
Where
"CHARSET"Method returns gettext-parser specific translation object (see below)
Example
import { readFileSync } from 'node:fs';
var input = readFileSync('en.mo');
var mo = gettextParser.mo.parse(input);
console.log(mo.translations['']); // output translations for the default context
If you have a translation object you can convert this to a valid MO file with
gettextParser.mo.compile(data) → Buffer
Where
Example
import { writeFileSync } from 'node:fs';
var data = {
...
};
var output = gettextParser.mo.compile(data);
writeFileSync('filename.mo', output);
If you are compiling a previously parsed translation object, you can override the output charset with the charset property (applies both for compiling mo and po files).
var obj = gettextParser.po.parse(inputBuf);
obj.charset = "windows-1257";
outputBuf = gettextParser.po.compile(obj);
Headers for the output are modified to match the updated charset.
By default gettext-parser uses pure JS iconv-lite for encoding and decoding non UTF-8 charsets. If you need to support more complex encodings that are not supported by iconv-lite, you need to add iconv as an additional dependency for your project (gettext-parser will detect if it is available and tries to use it instead of iconv-lite).
Parsed data is always in unicode but the original charset of the file can
be found from the charset property. This value is also used when compiling translations
to a mo or po file.
Headers can be found from the headers object and the value for a key is a string. This value will also be used when compiling.
Key casing isn't lowercased: the ~10 standard gettext headers (Language, Plural-Forms, Content-Type, ...) are recognized case-insensitively and normalized to their canonical name, while any other header (e.g. a tool-specific X-Poedit-* header) keeps whatever casing the source file used, unchanged (see #52).
Translations can be found from the translations object which in turn holds context objects for msgctxt. Default context can be found from translations[""].
Context objects include all the translations, where msgid value is the key. The value is an object with the following possible properties:
translator, reference, extracted, flag, previous.Example
{
"charset": "iso-8859-1",
"headers": {
"content-type": "text/plain; charset=iso-8859-1",
"plural-forms": "nplurals=2; plural=(n!=1);"
},
"translations": {
"": {
"": {
"msgid": "",
"msgstr": ["Content-Type: text/plain; charset=iso-8859-1\n..."]
}
},
"another context": {
"%s example": {
"msgctxt": "another context",
"msgid": "%s example",
"msgid_plural": "%s examples",
"msgstr": ["% näide", "%s näidet"],
"comments": {
"translator": "This is regular comment",
"reference": "/path/to/file:123"
}
}
}
}
}
Notice that the structure has both a headers object and a "" translation with the header string. When compiling the structure to a mo or a po file, the headers object is used to define the header. Header string in the "" translation is just for reference (includes the original unmodified data) but will not be used when compiling. So if you need to add or alter header values, use only the headers object.
If you need to convert gettext-parser formatted translation object to something else, eg. for jed, check out po2json.
MIT
Overall
Maintained
Code review
Latest release
Releases this year
410 followers · starred Dec 2022
60 followers · starred Oct 2022