How It Works
This page explains what happens when you run pinecone build.
The Bundling Pipeline
┌─────────────────┐
│ 1. Parse │ Read entry file and discover imports
└────────┬────────┘
│
┌────────▼────────┐
│ 2. Resolve │ Build dependency graph, detect cycles
└────────┬────────┘
│
┌────────▼────────┐
│ 3. Rename │ Prefix all identifiers to avoid collisions
└────────┬────────┘
│
┌────────▼────────┐
│ 4. Merge │ Combine modules in dependency order
└────────┬────────┘
│
┌────────▼────────┐
│ 5. Output │ Write single TradingView-compatible file
└─────────────────┘
Step 1: Parse
Pinecone reads your entry file and parses:
- PineScript AST - Using the pynescript library
- Export directives -
// @export functionName - Import directives -
// @import { fn } from "./file.pine"
Step 2: Resolve Dependencies
Starting from the entry file, Pinecone:
- Discovers all
// @importdirectives - Recursively parses imported files
- Builds a dependency graph
- Performs topological sort (dependencies before dependents)
- Detects circular dependencies
Example dependency graph:
main.pine
├── utils/math.pine
│ └── utils/constants.pine
└── utils/format.pine
└── utils/math.pine (already resolved)
Topological order: constants → math → format → main
Step 3: Rename Identifiers
To prevent naming collisions when modules are combined, Pinecone renames all top-level identifiers in dependency modules.
Before:
After:
Naming Convention
The prefix is derived from the file path:
| File Path | Prefix |
|---|---|
src/utils.pine |
__utils__ |
src/utils/math.pine |
__utils_math__ |
src/indicators/rsi.pine |
__indicators_rsi__ |
What Gets Renamed
- ✅ Variables
- ✅ Functions
- ✅ References to renamed identifiers
- ❌ Methods (called via dot notation, no collision risk)
- ❌ Entry file identifiers (stays as-is)
Step 4: Merge Modules
Modules are merged in topological order:
- Version annotation - From entry file
- Indicator/Strategy declaration - From entry file
- External imports - Deduplicated TradingView library imports
- Dependency modules - In topological order
- Entry module code - The main script
Step 5: Post-Processing
Before writing the output, Pinecone applies fixes for known issues:
Generic Type Syntax Fix
The pynescript library has a bug where generic types get malformed:
Import Deduplication
If multiple modules import the same TradingView library, duplicates are removed:
// Multiple modules import TradingView/ta/9
// Output contains only one import at the top:
import TradingView/ta/9 as ta
Example: Full Pipeline
Input files:
// src/main.pine
//@version=5
// @import { double } from "./utils.pine"
indicator("Test")
result = double(close)
plot(result)
Output:
//@version=5
indicator("Test")
// --- Bundled modules ---
// --- From: utils.pine ---
__utils__double(x) => x * 2
// --- Main ---
result = __utils__double(close)
plot(result)
Performance
Pinecone is fast because it:
- Only parses files once
- Caches the dependency graph
- Uses efficient AST transformations
For most projects, bundling takes less than a second.