Giac provides native Node.js bindings that allow you to leverage powerful computer algebra capabilities in your JavaScript applications. The bindings are built using Node.js Native Addons (N-API).
Installation
The Node.js package is no longer actively updated but remains functional for existing projects.
Install the giac package from npm:
Prerequisites
To build the native bindings from source, you need:
Node.js 10.0 or higher
C++ compiler with C++11 support
Python 2.7 or 3.x (for node-gyp)
GMP and MPFR libraries
sudo apt-get install build-essential libgmp-dev libmpfr-dev
Install windows-build-tools : npm install --global windows-build-tools
Quick Start
Basic Usage
Here’s a simple example of evaluating mathematical expressions:
const giac = require ( 'giac' );
// Evaluate expressions
console . log ( giac . evaluate ( "expand((x+y)^3)" ));
// Output: x^3+y^3+3*x*y^2+3*x^2*y
console . log ( giac . evaluate ( "expand((x+y)^4)" ));
// Output: x^4+y^4+4*x*y^3+6*x^2*y^2+4*x^3*y
console . log ( giac . evaluate ( "2^50" ));
// Output: 1125899906842624
Interactive REPL
The package includes a command-line interface:
This launches an interactive session:
This is a minimalist command line version of NodeGiac
Enter expressions to evaluate
Example: factor(x^4-1); simplify(sin(3x)/sin(x))
int(1/(x^4-1)); int(1/(x^4+1)^4,x,0,inf)
f(x):=sin(x^2); f'(2); f'(y)
Press CTRL-D to stop
1>> factor(x^4-1)
1<< (x-1)*(x+1)*(x^2+1)
API Reference
evaluate(expression)
Evaluates a Giac expression and returns the result as a string.
Parameters:
expression (string): The mathematical expression to evaluate
Returns:
(string): The result of the evaluation
Examples:
Algebra
Calculus
Differential Equations
Functions
Linear Algebra
const giac = require ( 'giac' );
// Factor polynomials
console . log ( giac . evaluate ( "factor(x^4-1)" ));
// Output: (x-1)*(x+1)*(x^2+1)
// Simplify expressions
console . log ( giac . evaluate ( "simplify(sin(3x)/sin(x))" ));
// Output: 3-4*sin(x)^2
// GCD computation
console . log ( giac . evaluate ( "gcd(x^4-1,x^3-1)" ));
// Output: x-1
Building Native Bindings
The native bindings are built using binding.gyp configuration:
Configuration
{
"targets" : [
{
"target_name" : "giac" ,
"sources" : [
"<!@(node -p \" require('fs').readdirSync('./src/giac/cpp/').map(f=>'src/giac/cpp/'+f).join(' ') \" )" ,
"src/nodegiac/cpp/nodegiac.cc"
],
"include_dirs" : [ "src/giac/headers" ],
"defines" : [
"GIAC_GGB" ,
"VERSION= \" 1.2.3 \" " ,
"IN_GIAC" ,
"HAVE_SYSCONF" ,
"HAVE_NO_HOME_DIRECTORY" ,
"TIMEOUT" ,
"HAVE_MPFR_1" ,
"HAVE_LIBMPFR"
]
}
]
}
"cflags_cc" : [ "-fexceptions" , "-fpermissive" ],
"cflags_cc!" : [ "-fno-rtti" ],
"link_settings" : {
"libraries" : [ "-lgmp" , "-lmpfr" ]
},
"defines+" : [ "HAVE_LIBPTHREAD" ]
"defines+" : [
"NO_STDEXCEPT" ,
"APPLE_SMART" ,
"NO_GETTEXT" ,
"CLANG"
],
"link_settings" : {
"libraries" : [ "-lgmp" , "-lmpfr" ]
},
"xcode_settings" : {
"GCC_ENABLE_CPP_RTTI" : "YES" ,
"OTHER_CPLUSPLUSFLAGS" : [ "-std=c++11" , "-stdlib=libc++" ]
}
"defines+" : [
"__VISUALC__" ,
"HAVE_NO_SYS_TIMES_H" ,
"HAVE_NO_PWD_H" ,
"MS_SMART"
],
"link_settings" : {
"libraries" : [ "-lmpir.lib" , "-lmpfr.lib" ]
}
Build from Source
# Clone repository
git clone < repository-ur l >
cd giac
# Install dependencies
npm install
# Build native addon
npm run build
Implementation Details
The Node.js binding is implemented using V8 and N-API:
#include <node.h>
#include <v8.h>
#include "giac.h"
using namespace v8 ;
using namespace giac ;
context ct;
void Evaluate ( const v8 :: FunctionCallbackInfo < Value > & args ) {
Isolate * isolate = Isolate :: GetCurrent ();
Local < Context > context = isolate -> GetCurrentContext ();
HandleScope scope (isolate);
std ::string line_out;
// Convert JS string to C++ string
v8 :: String ::Utf8Value param1 (isolate,
args [ 0 ]-> ToString (context). ToLocalChecked ());
std ::string line_in = std :: string ( * param1);
// Evaluate using Giac
gen g = gen (line_in, & ct);
try {
line_out = giac :: print ( giac :: eval (g, & ct), & ct);
} catch (runtime_error & err) {
line_out = std :: string ( "ERROR: " ) + err . what ();
}
// Return result to JavaScript
Local < Value > line_out_v8 = String :: NewFromUtf8 (
isolate, line_out . c_str (),
NewStringType ::kNormal). ToLocalChecked ();
args . GetReturnValue (). Set (line_out_v8);
}
NODE_MODULE (giac, Initialize)
Creating a REPL
Here’s how to create an interactive REPL using Node.js readline:
const giac = require ( 'giac' );
const readline = require ( 'readline' );
const rl = readline . createInterface ({
input: process . stdin ,
output: process . stdout ,
terminal: false
});
console . log ( "Giac REPL - Enter expressions to evaluate" );
console . log ( "Press CTRL-D to exit \n " );
let lineNumber = 1 ;
rl . on ( 'line' , function ( line ) {
// Echo input
console . log ( ` ${ lineNumber } >> ${ line } ` );
// Evaluate expression
const result = giac . evaluate ( line );
console . log ( ` ${ lineNumber } << ${ result } ` );
lineNumber ++ ;
});
rl . on ( 'close' , function () {
console . log ( " \n Goodbye!" );
process . exit ( 0 );
});
GeoGebra Mode
Enable GeoGebra-specific features:
const giac = require ( 'giac' );
// Enable GeoGebra mode
console . log ( giac . evaluate ( 'caseval("init geogebra")' ));
// Output: "geogebra mode on"
// Lists become sets in GeoGebra mode
console . log ( giac . evaluate ( '[1]' ));
// Output: {1}
// High precision evaluation
console . log ( giac . evaluate ( 'evalf(7,15)' ));
// Output: 7.00000000000000
// Disable GeoGebra mode
console . log ( giac . evaluate ( 'caseval("close geogebra")' ));
// Output: "geogebra mode off"
Advanced Usage
Processing Multiple Expressions
const giac = require ( 'giac' );
const expressions = [
'factor(x^4-1)' ,
'solve(x^2-3*x+2=0)' ,
'int(sin(x))' ,
'limit(sin(x)/x,x=0)'
];
expressions . forEach (( expr , index ) => {
console . log ( ` ${ index + 1 } . ${ expr } ` );
console . log ( ` => ${ giac . evaluate ( expr ) } \n ` );
});
Error Handling
const giac = require ( 'giac' );
function safeEvaluate ( expression ) {
try {
const result = giac . evaluate ( expression );
// Check for error prefix
if ( result . startsWith ( 'ERROR:' )) {
throw new Error ( result );
}
return result ;
} catch ( error ) {
console . error ( `Failed to evaluate " ${ expression } ":` , error . message );
return null ;
}
}
console . log ( safeEvaluate ( 'factor(x^2-1)' )); // Success
console . log ( safeEvaluate ( 'invalid syntax' )); // Error
Integration with Express
const express = require ( 'express' );
const giac = require ( 'giac' );
const app = express ();
app . use ( express . json ());
app . post ( '/evaluate' , ( req , res ) => {
const { expression } = req . body ;
if ( ! expression ) {
return res . status ( 400 ). json ({ error: 'Expression required' });
}
try {
const result = giac . evaluate ( expression );
res . json ({ expression , result });
} catch ( error ) {
res . status ( 500 ). json ({ error: error . message });
}
});
app . listen ( 3000 , () => {
console . log ( 'Giac API listening on port 3000' );
});
Batch expressions : Process multiple expressions in sequence to reuse the Giac context
Cache results : Store frequently-used computation results
Timeouts : Long computations may block the Node.js event loop
Worker threads : Consider using worker threads for CPU-intensive operations
Giac computations run on the main thread and may block the event loop for complex expressions. Consider implementing timeouts or using worker threads for production applications.
Troubleshooting
Build fails with 'gmp.h not found'
Install GMP development headers: Linux: sudo apt-get install libgmp-devmacOS: brew install gmpWindows: Ensure MPIR libraries are in your PATH
Module not found after installation
Try rebuilding the native addon:
Segmentation fault on evaluation
This usually indicates a memory issue. Make sure:
You’re using compatible Node.js and V8 versions
GMP/MPFR libraries are correctly installed
The expression syntax is valid
Next Steps
C++ Integration Learn about the underlying C++ library
API Reference Explore available Giac functions
WebAssembly Use Giac in web browsers
Algebra API Explore polynomial and algebra functions