Thank you for your interest in contributing to TinyFrameJS, the high-performance JavaScript engine for tabular data processing with a modular, functional architecture. We welcome contributions of all kinds β code, docs, benchmarks, ideas.
This repository is a monorepo part of the AlphaQuantJS ecosystem and contains:
- β packages/core: The core tabular engine with DataFrame, Series, and ColumnVector implementations
- β packages/io: Input/output functionality for CSV, JSON, Excel
- β packages/viz: Visualization methods for charts and plots
- β packages/quant: Technical analysis and quantitative methods
- β packages/utils: Shared utilities and helper functions
- β Vitest-based unit tests
- β
Benchmarks vs competitors in
/benchmarks
Project structure is in README.md
Allows adding new methods in a "plug-and-play" style β just create a file with your method and export it in a barrel file.
-
Create a file with your method
In thepackages/core/src/methods/dataframe/aggregation/directory, create a fileyourNew.js:/** * yourNew - example of a new aggregation method * * @param {{ validateColumn(frame, column): void }} deps - Dependencies * @returns {(frame: DataFrame, column: string) => any} - Function for working with DataFrame */ export const yourNew = ({ validateColumn }) => (frame, column) => { validateColumn(frame, column); // Your logic here return; /* result */ };
-
Add the method to the barrel file
Openpackages/core/src/methods/dataframe/aggregation/pool.jsand add:// Add along with other exports export { yourNew } from './yourNew.js';
-
Method Registration
All methods are automatically registered viaextendDataFramein the filepackages/core/src/methods/dataframe/aggregation/index.js:import { DataFrame } from '../../../core/DataFrame.js'; import { extendDataFrame } from '../../../core/extendDataFrame.js'; import * as pool from './pool.js'; // Dependencies import { validateColumn } from '../../../utils/validators.js'; const deps = { validateColumn }; // Register methods extendDataFrame(DataFrame.prototype, pool); // Export methods for direct use export * from './pool.js';
-
Using the new method
import { DataFrame } from '@tinyframejs/core'; const df = new DataFrame({ x: [1, 2, 3], y: [4, 5, 6] }); // The method is automatically available in DataFrame const result = df.yourNew('x');
Done! Your method works without needing to modify other files or the library core.
For specialized methods that belong to a specific domain (like technical analysis, visualization, etc.), use namespaces:
-
Create a method in the appropriate package
// packages/quant/src/methods/ta/sma.js export const sma = ({ validateColumn }) => (frame, column, period = 14) => { validateColumn(frame, column); // Implementation return result; };
-
Register with namespace
// packages/quant/src/methods/ta/index.js import { DataFrame } from '@tinyframejs/core'; import { extendDataFrame } from '@tinyframejs/core'; import * as taMethods from './pool.js'; // Register methods in the 'ta' namespace extendDataFrame(DataFrame.prototype, taMethods, { namespace: 'ta' });
-
Usage
import { DataFrame } from '@tinyframejs/core'; import '@tinyframejs/quant'; // Registers methods const df = new DataFrame({ close: [100, 101, 102, 101, 99] }); // Access through namespace const smaValues = df.ta.sma('close', 3);
For project organization, we use the following branch structure:
-
main- Production version.
- Ready for release.
- Each commit is stable and tested code.
-
dev- Main development branch.
- All completed feature branches are merged here.
- May contain minor bugs and improvements in progress.
- Regularly undergoes integration testing.
For each task, issue, or feature, create a separate branch from dev:
-
Naming format:
feature/<feature-name> fix/<issue-name-or-number> refactor/<description>
Examples:
feature/lazy-computationfix/null-pointer-issue-32refactor/dataframe-optimizations
After completing work on the task:
- β
Create a Pull Request (PR) from the feature branch to the
devbranch. - β Conduct code review and testing.
- β
After successful review, merge into
dev. - β Delete the feature branch after merging.
If a serious error is discovered in a release (the main branch), we quickly fix it through a special hotfix branch from main:
-
Naming format:
hotfix/<critical-issue>
Example:
hotfix/dataframe-critical-bug
After fixing:
- β
Merge the
hotfixbranch intomain. - β
Then merge
mainback intodevto incorporate the fixes into the development branch.
main (stable)
β
ββ dev (development)
β ββ feature/lazy-computation
β ββ feature/arrow-integration
β ββ fix/null-pointer-issue-32
β ββ refactor/dataframe-optimizations
β
ββ hotfix/dataframe-critical-bug (if urgent fix needed)
- β
Verify that the
devbranch is fully stable and tested. - β
Create a release PR from the
devbranch tomain. - β Conduct final review, CI/CD tests, and regression tests.
- β
Merge the PR into
main. - β
Create a git release tag (e.g.,
v1.0.0) to mark the stable release point.
Example:
git checkout main
git merge dev
git tag v1.0.0
git push origin main --tags-
β Pull Requests (PR): Perform mandatory code reviews and tests before merging.
-
β Automation through CI/CD (GitHub Actions): Run automated testing, linting, and benchmarking.
-
β Branch protection rules on GitHub: Protect
mainanddevbranches from accidental direct commits. Configure mandatory PR reviews before merging. -
β Semantic Versioning (SemVer): Strictly follow semantic versioning (
1.0.0,1.1.0,1.1.1).
1.0.0β first stable release.1.0.1β bug fixes and minor corrections.1.1.0β new features that maintain backward compatibility.2.0.0β release with changes that break backward compatibility.
- Commit small changes frequently with informative messages.
- Create issues and PRs for each task.
- Regularly merge the
devbranch into your feature branches to avoid conflicts. - Use Squash/Merge commits for a clean history.
- Monitor stability and test coverage through CI/CD.
- Fork this repo on GitHub
- Clone your fork locally:
git clone git@github.com:AlphaQuantJS/tinyframejs.git cd tinyframejs npm install - Create a feature branch:
git checkout -b feat/your-feature-name
- Implement your feature or fix inside
src/ - Run tests and linting before pushing (see workflow below)
- Push and open a Pull Request to the
mainbranch
Please review our Coding Guidelines for:
- Performance tips for V8
- Data integrity and numerical precision
- Modular and reusable function design
- Memory-efficient handling of large datasets
- Code builds with
pnpm build - Added or updated relevant tests in the appropriate package
- Methods properly registered with
extendDataFrame - Namespaces used for domain-specific methods
- Follows ESLint/Prettier rules
- Descriptive commit message (see below)
- Linked to a GitHub Issue (if applicable)
- Clear description in PR body of what was changed and why
- If change is test-only or doc-only, ensure CI does not fail due to lack of coverage
- If new code is added, ensure at least minimal test coverage is present (to trigger coverage report upload)
pnpm formatπ Automatically applies the .prettierrc style to all .js, .json, .md, .yml, etc.
pnpm lint --fixπ Fixes linting errors and style, including JSDoc, spaces, indents, no-unused-vars, etc.
pnpm testπ Runs all tests (via Vitest) and checks that code is not broken.
pnpm coverageπ Generates coverage/lcov.info and prints the report to the console.
git add .
git commit -m "feat: describe your change"π This will automatically trigger:
npx lint-stagednpx prettier --writeon staged fileseslint --fixon staged.js/.ts
pnpm format && pnpm lint --fix && pnpm testWe use Conventional Commits for changelogs and releases.
<type>(scope): short summary
feat(core): add corrMatrix support
fix(frame): handle NaN edge case in rollingMean
docs(readme): add usage examples
Common types:
| Type | Description |
|---|---|
| feat | New feature |
| fix | Bug fix |
| docs | Documentation-only changes |
| refactor | Code refactor without behavioral change |
| test | Adding or updating tests |
| chore | Infrastructure, config, CI, etc. |
- Keep pull requests small and focused
- Add tests for each new piece of logic
- Document public functions with JSDoc
- Use dependency injection pattern for all methods
- Register methods properly with
extendDataFrame - Use namespaces for domain-specific methods
- Benchmark performance-critical paths
- Update
examples/when introducing new APIs
- Run tests via
pnpm test(all packages) orpnpm -F @tinyframejs/[package] test(specific package) - Test through the DataFrame API, not internal functions
- Coverage is uploaded to Codecov
- Benchmarks are located in
benchmarks/ - Guard tests protect against performance/memory regressions
Use GitHub Issues for:
- Bugs and regressions
- Feature suggestions
- Discussion prompts
We tag beginner-friendly tasks as good first issue.
- See
examples/for real-world usage - Contribute examples, notebooks, articles, or benchmark comparisons!
- Ask in GitHub Discussions
- Submit new ideas via PR or Issues
- Mention us on Twitter: @AlphaQuantJS
Thanks again for being part of the TinyFrameJS open-source journey π Let's build next-gen tools for financial analysis and large-scale data processing in JavaScript together β‘