日本のことわざデータセット
A structured, production-grade dataset of Japanese proverbs with bilingual meanings, examples, and JLPT levels.
npm install kotowaza
Meanings in Indonesian & English for every proverb.
Kanji, hiragana, and romaji for each entry.
Real-world usage with translations.
Pure JSON with lightweight query helpers.
Thematic tags and JLPT level metadata.
Search across Japanese, romaji, and meanings.
const kotowaza = require('kotowaza');
// Get all proverbs
console.log(`Loaded ${kotowaza.count()} proverbs`);
// Look up by ID
const entry = kotowaza.get('nanakorobi-yaoki');
console.log(entry.japanese); // 七転び八起き
console.log(entry.meaning.en); // No matter how many times...
// Search across all fields
kotowaza.search('猿'); // → entries with 猿
kotowaza.search('monkey'); // → entries with "monkey"
// Filter by tag or JLPT level
kotowaza.byTag('motivation');
kotowaza.byJlpt('N3');
// Random proverb (great for "Quote of the Day"!)
const daily = kotowaza.random();
// Direct link to Jepang.org
kotowaza.url('nanakorobi-yaoki');
// → https://jepang.org/peribahasa/nanakorobi-yaoki/
| Method | Returns | Description |
|---|---|---|
all() |
object[] |
All kotowaza entries |
get(id) |
object|null |
Single entry by slug ID |
search(query) |
object[] |
Search Japanese, romaji, meanings |
byTag(tag) |
object[] |
Filter by thematic tag (English) |
byTagId(tag) |
object[] |
Filter by Indonesian tag |
byJlpt(level) |
object[] |
Filter by JLPT level |
random() |
object |
One random entry |
count() |
number |
Total entries |
tags() |
string[] |
All unique English tags (sorted) |
tagsId() |
string[] |
All unique Indonesian tags (sorted) |
jlptLevels() |
string[] |
All JLPT levels in dataset |
url(id) |
string |
Full Jepang.org URL |
Each entry follows this structure:
{
"id": "nanakorobi-yaoki", // URL slug
"japanese": "七転び八起き", // Original kanji
"reading": "ななころびやおき", // Hiragana
"romaji": "Nanakorobi Yaoki", // Romanized
"literal": "Fall seven times...", // Literal translation
"meaning": {
"id": "Indonesian meaning...",
"en": "English meaning..."
},
"tags": ["motivation", "numbers"],
"tags_id": ["motivasi", "angka"],
"jlpt": "N4",
"equivalent": {
"id": "Equivalent Indonesian proverb...",
"en": "Equivalent English proverb..."
},
"examples": [{
"ja": "Japanese sentence...",
"romaji": "Romanized...",
"id": "Indonesian translation..."
}],
"related": ["related-id-1"]
}
const kotowaza = require('kotowaza');
// Deterministic "daily" proverb based on the date
function getDailyProverb() {
const all = kotowaza.all();
const today = new Date();
const dayIndex = (today.getFullYear() * 366 + today.getMonth() * 31 + today.getDate()) % all.length;
return all[dayIndex];
}
const daily = getDailyProverb();
console.log(`📜 ${daily.japanese}`);
console.log(`💬 ${daily.meaning.en}`);
const express = require('express');
const kotowaza = require('kotowaza');
const app = express();
// GET /api/proverbs?tag=motivation&jlpt=N3
app.get('/api/proverbs', (req, res) => {
let results = kotowaza.all();
if (req.query.tag) results = kotowaza.byTag(req.query.tag);
if (req.query.jlpt) {
results = results.filter(e => e.jlpt === req.query.jlpt.toUpperCase());
}
if (req.query.q) results = kotowaza.search(req.query.q);
res.json({ count: results.length, data: results });
});
// GET /api/proverbs/random
app.get('/api/proverbs/random', (req, res) => {
res.json(kotowaza.random());
});
// GET /api/proverbs/:id
app.get('/api/proverbs/:id', (req, res) => {
const entry = kotowaza.get(req.params.id);
if (!entry) return res.status(404).json({ error: 'Not found' });
res.json(entry);
});
const kotowaza = require('kotowaza');
// Build a study deck for a specific JLPT level
function buildStudyDeck(level) {
return kotowaza.byJlpt(level).map(entry => ({
front: entry.japanese,
hint: entry.reading,
back: entry.meaning.en,
example: entry.examples[0]?.ja,
url: kotowaza.url(entry.id)
}));
}
const n3Deck = buildStudyDeck('N3');
console.log(`📚 ${n3Deck.length} flashcards for JLPT N3`);
// Shuffle and quiz
const card = n3Deck[Math.floor(Math.random() * n3Deck.length)];
console.log(`Q: What does "${card.front}" mean?`);
console.log(`A: ${card.back}`);
const kotowaza = require('kotowaza');
// Lightweight search for autocomplete / typeahead
function autocomplete(query) {
if (!query || query.length < 2) return [];
return kotowaza.search(query).slice(0, 5).map(entry => ({
id: entry.id,
label: `${entry.japanese} (${entry.romaji})`,
preview: entry.meaning.en.slice(0, 60) + '...'
}));
}
console.log(autocomplete('fall'));
// [{ id: 'nanakorobi-yaoki', label: '七転び八起き (Nanakorobi Yaoki)', ... }]
const kotowaza = require('kotowaza');
// !kotowaza — random proverb
function handleCommand(command, args) {
if (command === '!kotowaza') {
const entry = args[0] ? kotowaza.get(args[0]) : kotowaza.random();
if (!entry) return '❌ Proverb not found.';
return [
`**${entry.japanese}** (${entry.romaji})`,
`> _${entry.meaning.en}_`,
entry.equivalent?.en ? `🔗 Similar: "${entry.equivalent.en}"` : '',
`📖 ${kotowaza.url(entry.id)}`
].filter(Boolean).join('\n');
}
// !kotowaza-quiz — quiz mode
if (command === '!kotowaza-quiz') {
const entry = kotowaza.random();
return `❓ What does **"${entry.japanese}"** mean?\n||${entry.meaning.en}||`;
}
}
const kotowaza = require('kotowaza');
// Generate pages for each proverb (e.g. in 11ty .eleventy.js)
module.exports = function(eleventyConfig) {
eleventyConfig.addCollection('proverbs', () => {
return kotowaza.all().map(entry => ({
...entry,
permalink: `/proverbs/${entry.id}/`,
fullUrl: kotowaza.url(entry.id)
}));
});
// Shortcode for embedding a random proverb
eleventyConfig.addShortcode('randomProverb', () => {
const p = kotowaza.random();
return `<blockquote class="kotowaza">
<p lang="ja">${p.japanese}</p>
<footer>${p.meaning.en}</footer>
</blockquote>`;
});
};