
Security News
The Hidden Blast Radius of the Axios Compromise
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.
@millcrest/libsvmts
Advanced tools
Modern TypeScript wrapper for libsvm with WebAssembly support and sklearn-like API
Modern TypeScript wrapper for libsvm with WebAssembly support and an sklearn-like API. This library brings powerful Support Vector Machine capabilities to TypeScript/JavaScript with a familiar, Pythonic interface inspired by scikit-learn.
npm install @millcrest/libsvmts
import { SVC } from "@millcrest/libsvmts";
// Create and configure classifier
const clf = new SVC({
kernel: 'rbf',
C: 1.0,
gamma: 'scale',
});
// Prepare data
const x_train = [[0, 0], [1, 1], [1, 0], [0, 1]];
const y_train = [0, 0, 1, 1];
// Train model
await clf.fit(x_train, y_train);
// Make predictions
const predictions = clf.predict([[0.5, 0.5]]);
console.log(predictions); // [0]
// Get accuracy
const accuracy = clf.score(x_train, y_train);
console.log(`Accuracy: ${(accuracy * 100).toFixed(2)}%`);
// Clean up
clf.free();
import { SVR } from "@millcrest/libsvmts";
// Create regressor
const regressor = new SVR({
kernel: 'rbf',
C: 1.0,
epsilon: 0.1,
});
// Prepare data
const x_train = [[0], [1], [2], [3], [4]];
const y_train = [0, 1, 4, 9, 16]; // y = x^2
// Train model
await regressor.fit(x_train, y_train);
// Make predictions
const predictions = regressor.predict([[2.5]]);
console.log(predictions); // ~6.25
// Get R² score
const r2 = regressor.score(x_train, y_train);
console.log(`R² Score: ${r2.toFixed(4)}`);
// Clean up
regressor.free();
Mimics sklearn.svm.SVC
Constructor Parameters:
interface SVCParams {
C?: number; // Regularization parameter (default: 1.0)
kernel?: 'linear' | 'poly' | 'rbf' | 'sigmoid' | 'precomputed'; // default: 'rbf'
degree?: number; // Degree for poly kernel (default: 3)
gamma?: number | 'scale' | 'auto'; // Kernel coefficient (default: 'scale')
coef0?: number; // Independent term in kernel (default: 0.0)
tol?: number; // Tolerance for stopping (default: 1e-3)
shrinking?: boolean; // Use shrinking heuristic (default: true)
probability?: boolean; // Enable probability estimates (default: false)
cacheSize?: number; // Kernel cache size in MB (default: 200)
classWeight?: 'balanced' | Record<number, number> | null; // Class weights
verbose?: boolean; // Verbose output (default: false)
maxIter?: number; // Max iterations, -1 for no limit (default: -1)
decisionFunctionShape?: 'ovr' | 'ovo'; // Decision function shape (default: 'ovr')
breakTies?: boolean; // Break ties by confidence (default: false)
randomState?: number | null; // Random seed (default: null)
}
Methods:
async fit(X: Matrix, y: Vector): Promise<this> - Fit the SVM modelpredict(X: Matrix): Vector - Predict class labelspredictProba(X: Matrix): PredictionWithProba[] - Predict class probabilities (requires probability: true)decisionFunction(X: Matrix): Matrix - Compute decision function valuesscore(X: Matrix, y: Vector): number - Return mean accuracygetModelInfo(): ModelInfo | null - Get model informationfree(): void - Free model memoryMimics sklearn.svm.SVR
Constructor Parameters:
interface SVRParams {
C?: number; // Regularization parameter (default: 1.0)
kernel?: 'linear' | 'poly' | 'rbf' | 'sigmoid' | 'precomputed'; // default: 'rbf'
degree?: number; // Degree for poly kernel (default: 3)
gamma?: number | 'scale' | 'auto'; // Kernel coefficient (default: 'scale')
coef0?: number; // Independent term in kernel (default: 0.0)
epsilon?: number; // Epsilon in epsilon-SVR (default: 0.1)
tol?: number; // Tolerance for stopping (default: 1e-3)
shrinking?: boolean; // Use shrinking heuristic (default: true)
cacheSize?: number; // Kernel cache size in MB (default: 200)
verbose?: boolean; // Verbose output (default: false)
maxIter?: number; // Max iterations, -1 for no limit (default: -1)
}
Methods:
async fit(X: Matrix, y: Vector): Promise<this> - Fit the SVM modelpredict(X: Matrix): Vector - Predict target valuesscore(X: Matrix, y: Vector): number - Return R² scoregetModelInfo(): ModelInfo | null - Get model informationfree(): void - Free model memorytype Matrix = number[][]; // 2D array for features
type Vector = number[]; // 1D array for labels/targets
interface PredictionWithProba {
label: number;
probabilities: Record<number, number>;
}
interface ModelInfo {
nClasses: number;
classes?: number[];
nSupportPerClass?: number[];
nSupport: number;
supportVectorIndices: number[];
isFitted: boolean;
}
# Clone with submodules
git clone --recursive git@github.com:millcrest/libsvmts.git
cd libsvmts
# Or if already cloned
git submodule update --init --recursive
# Install dependencies
npm install
# Build everything
npm run build
Note: The first npm install will warn that WASM isn't built yet - that's expected.
Choose one of these methods:
Option 1: System-wide (recommended)
# Follow official guide: https://emscripten.org/docs/getting_started/downloads.html
Option 2: Using Docker
docker run -v $(pwd):/src -w /src emscripten/emsdk make build
Option 3: Local emsdk (if you prefer)
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
cd ..
npm run build # Build WASM + TypeScript
make build # Build WASM only (requires emcc in PATH)
npm run build:ts # Build TypeScript only
npm run build:ts
### Development Commands
```bash
npm run dev # Watch mode for TypeScript
npm run build # Build everything (WASM + TS)
npm run build:wasm # Build WASM only
npm run build:ts # Build TypeScript only
npm run test # Run tests
npm run test:watch # Watch mode for tests
npm run lint # Lint code
npm run format # Format code
npm run typecheck # Type check without building
const clf = new SVC({
kernel: 'rbf',
probability: true, // Enable probability estimates
});
await clf.fit(x_train, y_train);
// Get predictions with probabilities
const predictions = clf.predictProba(X_test);
predictions.forEach(pred => {
console.log(`Predicted: ${pred.label}`);
console.log(`Probabilities:`, pred.probabilities);
});
// Balanced class weights
const clf = new SVC({
classWeight: 'balanced'
});
// Manual class weights
const clf = new SVC({
classWeight: {
0: 1.0,
1: 2.0 // Give class 1 twice the weight
}
});
const clf = new SVC({
decisionFunctionShape: 'ovr' // One-vs-Rest
});
await clf.fit(x_train, y_train);
// Get decision function values
const decisionValues = clf.decisionFunction(X_test);
// Get model information
const modelInfo = clf.getModelInfo();
console.log('Support vectors:', modelInfo.nSupport);
console.log('Classes:', modelInfo.classes);
// Serialize model (TODO: implementation pending)
// const serialized = clf.serializeModel();
This project uses Vitest for both unit and integration tests.
# Run all tests (unit + integration)
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with UI
npm run test:ui
# Run with coverage
npm run test:coverage
This project is licensed under the BSD 3-Clause License - see the LICENSE file for details.
libsvm is also licensed under the BSD 3-Clause License. See the libsvm license for details.
FAQs
Modern TypeScript wrapper for libsvm with WebAssembly support and sklearn-like API
We found that @millcrest/libsvmts demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
The Axios compromise shows how time-dependent dependency resolution makes exposure harder to detect and contain.

Research
A supply chain attack on Axios introduced a malicious dependency, plain-crypto-js@4.2.1, published minutes earlier and absent from the project’s GitHub releases.

Research
Malicious versions of the Telnyx Python SDK on PyPI delivered credential-stealing malware via a multi-stage supply chain attack.