Export Tiers
When you write a function in Rust, Python, or Java, Transit can find it automatically. You do not need to register functions manually or write special configuration. Transit scans your code and discovers functions based on simple rules.
The Three Tiers
Section titled “The Three Tiers”Think of tiers like levels of permission:
- Tier 1 (default): Transit finds functions that are already public in your language. No changes needed.
- Tier 2 (file-level): You put a comment at the top of a file to export everything in that file.
- Tier 3 (function-level): You put a comment above a specific function to export it, even if it is private.
Most people only need Tier 1.
Tier 1: Public Functions (No Changes Needed)
Section titled “Tier 1: Public Functions (No Changes Needed)”Transit finds functions that are public by your language’s own rules:
Any function with pub fn is found automatically:
// Transit finds this — it is a pub fnpub fn process_job(job: FileJob) -> ProcessResult { // your code here}
// Transit does NOT find this — it is not pubfn internal_helper(data: &[u8]) -> String { format!("Internal: {} bytes", data.len())}Important: For Transit to call your Rust function from JavaScript, it must also be annotated with #[napi]. Here is a complete example:
use napi_derive::napi;
#[napi]pub fn process_job(job: String) -> String { format!("Processed: {}", job)}And your Cargo.toml must include:
[lib]crate-type = ["cdylib"]
[dependencies]napi = "2"napi-derive = "2"Python
Section titled “Python”Any function defined at the top level of a file (not inside a class) is found:
# Transit finds this — it is a top-level defdef process_data(data): return transform(data)
# Transit also finds class methodsclass DataProcessor: def process(self, data): # Found as "DataProcessor.process" return transform(data)
# Transit does NOT find this — it starts with underscoredef _private_helper(data): return optimized_path(data)Important: Your Python function receives a JSON string, not a parsed dictionary. You must call json.loads():
import json
def process_data(args_json): args = json.loads(args_json) # Now args is a dictionary items = args.get("items", []) return json.dumps({"count": len(items)})Any public method is found:
// Transit finds this — it is a public methodpublic String processJob(String argsJson) { return "{\"result\": \"done\"}";}
// Transit does NOT find this — it is privateprivate String internalHelper(String data) { return data.toUpperCase();}C and C++
Section titled “C and C++”Any function whose signature is declared via the generated glue header is found automatically:
void process_chunk(const char* args_json, char** result_json);void fast_compute(const char* args_json, char** result_json);Transit detects these signatures from the generated headers and exports the corresponding implementations.
JavaScript/TypeScript
Section titled “JavaScript/TypeScript”Any exported function is found:
// Transit finds this — it is exportedexport function processJob(data) { return { result: "done" };}
// Transit does NOT find this — it is not exportedfunction internalHelper(data) { return data.toUpperCase();}Tier 2: File-Level Export
Section titled “Tier 2: File-Level Export”If you want to export all functions in a file (including private ones), add a comment at the very top:
// transit:file// All public functions in this file are exported
pub fn helper_a() -> String { ... }pub fn helper_b() -> String { ... }Python
Section titled “Python”# transit:file
def process(data): return transform(data)// transit:file
public class Utils { public static String format(String input) { ... } public static String parse(String input) { ... }}Tier 3: Function-Level Export
Section titled “Tier 3: Function-Level Export”If you want to export a specific private function, add a comment directly above it:
// transit:functionfn internal_helper(data: &[u8]) -> String { format!("Internal: {} bytes", data.len())}Python
Section titled “Python”# transit:functiondef _private_transform(data): return optimized_path(data)JavaScript
Section titled “JavaScript”// transit:functionfunction computeHash(buffer) { // ...}Key point: Tier 3 overrides the language’s privacy rules. A function that would normally be hidden becomes callable from other languages.
Name Disambiguation
Section titled “Name Disambiguation”If two files export functions with the same name, use the file name to pick which one:
// If lib.rs and utils.rs both export "process":await rs["lib"]["process"](data) // calls lib.rs's processawait rs["utils"]["process"](data) // calls utils.rs's process
// Dot notation also works:await rs.lib.process(data)What the Scanner Produces
Section titled “What the Scanner Produces”When Transit scans your code, it creates a list of discovered functions:
{ "language": "rust", "sourceFile": "/path/to/lib.rs", "functionName": "process_job", "signature": "pub fn process_job(job: FileJob) -> ProcessResult", "exportTier": 1}This list is used by Transit to know which functions are available and how to call them.
Naming Between Languages
Section titled “Naming Between Languages”Transit automatically handles naming differences between languages:
- Rust uses
snake_case(likeprocess_general) - JavaScript uses
camelCase(likeprocessGeneral) - Java uses
camelCase(likeprocessSpecialized)
You can call functions using either style:
// Both work for a Rust function named process_general:await rs.process_general(data)await rs.processGeneral(data)