Calculating the Difference Between JSON Files
Learn how to find missing translations in JSON files with dictionaries.

Daniel Gustaw
• 3 min read

In this article, we will demonstrate how to create a function that identifies the differences between two JSON files.
From an educational standpoint, this serves as an excellent example of using recursive functions. From a practical perspective, it’s a valuable tool for managing translations.
To begin, we’ll create a command that reads the files and prints all keys present in the first file but missing in the second file to the standard output.
We will start by checking if the files indicated as arguments exist:
const fs = require('fs')
const pathBase = `${process.cwd()}/${process.argv[2]}`;
const pathComp = `${process.cwd()}/${process.argv[3]}`;
if (!fs.existsSync(pathBase)) {
console.error(`File ${pathBase} not existst`);
process.exit()
}
if (!fs.existsSync(pathComp)) {
console.error(`File ${pathComp} not existst`);
process.exit()
}
Next, we’ll read the contents of these files and convert JSON to objects:
const base = JSON.parse(fs.readFileSync(pathBase).toString());
const comp = JSON.parse(fs.readFileSync(pathComp).toString());
Now, we’ll define a function for finding differences:
function getDiff(a, b) {
const res = {};
for (let key in a) {
if (a.hasOwnProperty(key)) {
if (!b.hasOwnProperty(key)) {
res[key] = a[key]
} else {
if (typeof a[key] === 'object') {
res[key] = getDiff(a[key], b[key])
}
}
if (res[key] && !Object.keys(res[key]).length) {
delete res[key];
}
}
}
return res;
}
This function takes a pair of objects and iterates through the keys of the first (base) object. If the second object (comparison) does not have the key, it is added to the result. If the key is present, it checks if the type is an object and, if so, recursively calls the getDiff function.
Finally, we delete keys with empty objects before displaying the results:
process.stdout.write(JSON.stringify(getDiff(base, comp)))
This program does not support arrays. For translation files, they aren’t necessary. If you want to read about more advanced methods for comparing JSON files, a good starting point is a thread on Stack Overflow:
Using jq or alternative command line tools to compare JSON files
Now, let’s see how the program works in practice with translation files. The first file, en_old.json, was prepared manually and covers all translations in the application, while the second file, en.json, was generated by i18next. The issue is that i18next did not detect all translations.
At first, I sorted both files manually using the service: codeshack.io/json-sorter
https://codeshack.io/json-sorter/
Next, I used diffchecker
to find the differences between them:
https://www.diffchecker.com/yffDMWff
Then I created a file with the missing translations:
node ../DevTools/json-diff.js src/locales/en_old.json src/locales/en.json > src/locales/en-codes.json
The file, displayed and formatted by jq, looks like this:
We can see that it includes all the missing keys.
When importing translation files, we can use the deepmerge package. The i18n configuration file might look like this:
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import deepmerge from 'deepmerge'
import en from 'vuetify/lib/locale/en'
import pl from 'vuetify/lib/locale/pl'
Vue.use(VueI18n);
const messages = {
en: deepmerge(
require('@/locales/en-codes.json'),
require('@/locales/en.json'),
{$vuetify: en}
),
pl: deepmerge(
require('@/locales/pl-codes.json'),
require('@/locales/pl.json'),
{$vuetify: pl}
),
};
export default new VueI18n({
locale: process.env.VUE_APP_I18N_LOCALE || 'en',
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
messages,
})
export const languages = [
{text: 'lang.pl', value: 'pl'},
{text: 'lang.en', value: 'en'},
];
If you have any experiences related to automating translation work or recommendations for tools and scripts, feel free to share them in the comments. I’m interested in learning about the tools and approaches you use.
Other articles
You can find interesting also.

How to configure SSL in local development
Setting up an https connection on the localhost domain can be challenging if you're doing it for the first time. This post is a very detailed tutorial with all the commands and screenshots.

Daniel Gustaw
• 12 min read
![Pulumi - Infrastructure as a Code [ Digital Ocean ]](/_astro/f370e14e-6fd0-48ef-b689-02d89d85bfb7_ZzxruJ.png)
Pulumi - Infrastructure as a Code [ Digital Ocean ]
With Pulumi you can define your it infrastructure in your file described by your favourite programming language. This article shows how to do it.

Daniel Gustaw
• 9 min read

Scraping from money.pl in 30 lines of code.
See a simple case study of downloading and processing data from a paginated table.

Daniel Gustaw
• 8 min read