-
Notifications
You must be signed in to change notification settings - Fork 0
Adding a Language
Arham-Qureshi edited this page Jul 21, 2026
·
1 revision
codebase-vis can parse any language with a tree-sitter grammar. This guide walks you through adding support for a new language.
Adding a language requires changes in 4-5 files:
src/parser/{language}.js # New parser module
src/parser/index.js # Register in GRAMMAR_MAP
src/parser/languages.js # Add language metadata
src/parser/parse-worker.js # If grammar needs native bindings
test/parser/{language}.test.js # Tests
npm install tree-sitter-{language}Check if the grammar is already listed in package.json dependencies.
Create src/parser/{language}.js. It must export:
-
grammar— the tree-sitter language grammar -
extractDependencies(node)— returnsstring[]of import paths -
extractEntities(node)— returns{ classes: string[], functions: string[], methods: string[], docstrings: string[] }
import { promises as fs } from 'node:fs'
import { resolve } from 'node:path'
const query = `
; Dependency query
(import_statement
(string (string_fragment) @import))
; Entity queries
(class_declaration
name: (identifier) @class_name)
(function_declaration
name: (identifier) @function_name)
`
const methodQuery = `
(class_body
(method_definition
name: (property_identifier) @method_name))
`
const docstringQuery = `
(comment) @docstring
`
export const grammar = await import('tree-sitter-{language}').then(m => m.default || m)
export function extractDependencies(node) {
const deps = new Set()
const matches = node.querySelectorAll(query)
for (const match of matches) {
if (match.captures.import) {
deps.add(match.captures.import.text)
}
}
return [...deps]
}
export function extractEntities(node) {
const classes = []
const functions = []
const methods = []
const docstrings = []
// Extract using query captures
// Deduplicate methods from functions
return { classes, functions, methods, docstrings }
}| Technique | Implementation |
|---|---|
| Dependency capture | S-expression query matching import statements |
| Entity deduplication | Use AST position keys (startIndex-endIndex) with Set
|
| Method exclusion | Methods found inside class bodies → separate from top-level functions |
| Docstring association | Docstrings immediately preceding entities are attached to them |
| Path stripping | Strip quotes, @, ./, angle brackets from captured paths |
In src/parser/index.js, add your language:
const GRAMMAR_MAP = {
// ... existing entries ...
'.ext': { grammar: yourLanguageGrammar, parser: '{language}' },
}Add your extension to KNOWN_EXTENSIONS if not already covered.
In src/parser/languages.js:
export const LANGUAGES = [
// ... existing entries ...
{
name: 'YourLanguage',
extensions: ['.ext1', '.ext2'],
parser: '{language}',
color: '#yourColor',
defaultIgnores: ['build/', '*.ext_obj'],
},
]If your language has stack markers for init detection, add to STACK_MARKERS:
export const STACK_MARKERS = [
// ... existing entries ...
{ name: 'yourstack', markerFiles: ['your.config.js'], priority: 5 },
]If your grammar requires native bindings (most do), ensure src/parser/parse-worker.js imports it:
// Add to the worker's local GRAMMAR_MAP
const GRAMMAR_MAP = {
// ... existing entries ...
}Create test/parser/{language}.test.js:
import { test } from 'node:test'
import assert from 'node:assert'
import { parseFile } from '../../src/parser/index.js'
test('parses imports', async () => {
const result = await parseFile('path/to/test/file.ext')
assert.ok(result.dependencies.includes('expected-dependency'))
})
test('extracts entities', async () => {
const result = await parseFile('path/to/test/file.ext')
assert.ok(result.entities.classes.includes('ExpectedClass'))
})Study these existing parsers for reference:
| Language | File | Key Patterns |
|---|---|---|
| JavaScript | src/parser/javascript.js |
ES imports, CommonJS, dynamic imports |
| Python | src/parser/python.js |
Absolute/relative imports, decorator handling |
| C++ | src/parser/cpp.js |
System vs local includes, angle bracket stripping |
| Go | src/parser/go.js |
Simple import spec, quoted string stripping |
| Rust | src/parser/rust.js |
Use declarations, extern crate |