Getting Started With Chance for Probabilistic Programming
Chance is a domain-specific language that lets you define probabilistic models and run inference on them. It compiles down to JavaScript and runs in browsers or Node.js. The appeal is real if you need to build Bayesian models without managing the math manually. I first ran into this when a client needed a custom ranking system for their internal search tool. They wanted to incorporate uncertainty into how items were scored, which meant writing a full Bayesian model. We used Chance for that. The model itself was straightforward, but the inference part took some finessing.
Understanding How Chance Works
At its core, Chance uses a syntax that looks like JavaScript. You declare random variables using primitives like gaussian, bernoulli, or dirichlet. The framework handles the graph construction and then applies sampling-based inference under the hood. Most commonly it uses Markov chain Monte Carlo, specifically Metropolis-Hastings with adaptive proposal tuning. Here is what a basic model looks like: var mu = gaussian(0, 1);
var x = [];
for (var i = 0; i < 10; i++) {
x.push(gaussian(mu, 1));
}
That defines a hierarchical model where you have a shared mean with ten observed data points. To run inference, you pass observed values and call the sample method. The library returns posterior samples for the unknown parameters. The learning curve is gentle compared to writing TensorFlow Probability or Stan models from scratch, but it is not frictionless. You give up a lot of control over the inference algorithm. If your model has complex dependencies or multimodal posteriors, the default sampler can struggle.
Get the Full Details

Installing and Running It
You can install Chance through npm: npm install chance Or grab it directly from the GitHub repository at https://github.com/ProbabilisticCognition/chance. There is no official package manager presence beyond npm, and the project has been relatively quiet on updates in recent years. That matters if you are building something production-critical.
Once installed, you structure your code in a single file. Define the model, attach observations, and call inference. Here is a practical example using a logistic regression model for binary classification: var n = 100;
var weights = dirichlet([1, 1]);
var logits = [];
for (var i = 0; i < n; i++) {
logits.push(bernoulli(sigmoid(weights[0] + weights[1] * data[i])));
} Then you run the sampler with observed labels and extract posterior samples for the weight parameters. The output is an array of samples you can analyze with any statistics library.
Common Pitfalls and What I Learned the Hard Way
One issue that cost me a couple of days involved identifiability in a mixture model. I was building a simple Gaussian mixture with two components, and the sampler kept producing degenerate results where one component collapsed to a single point. The problem was not the code, it was the model. Mixture models are notoriously label-swap symmetric, and the default Metropolis-Hastings sampler does not handle that gracefully. The workaround was to add an ordering constraint on the component means, forcing component one to always have a lower mean than component two. This broke the symmetry and the sampler behaved. It is a standard trick in the Bayesian modeling community, but it is not documented prominently in Chance materials. Another thing to watch out for is performance. For models with more than a few dozen latent variables, the sampling can become very slow. I ran a model with about 50 parameters once and the inference took roughly forty minutes on a decent laptop. That is not acceptable for iterative development. I ended up simplifying the model structure and reducing the parameter count, which brought runtime down to under two minutes.

If you are working with larger datasets or more complex models, you should seriously consider Stan or PyMC instead. They have more mature samplers, including Hamiltonian Monte Carlo, which converges much faster on high-dimensional problems. Chance is fine for small to medium models where rapid prototyping matters more than raw speed.
When to Use Chance and When Not To
Use Chance when you need a lightweight probabilistic programming tool that runs in the browser, when your models are small enough for MCMC to work, or when you want to avoid setting up a Python environment. It is also reasonable for teaching purposes because the syntax is accessible. Do not use it when you need production-grade inference speed, when your model has many latent variables, or when you require advanced inference methods like variational inference or parallel tempering. In those cases, you will hit walls quickly and wish you had started elsewhere. The project also lacks an active maintainer ecosystem. There are not many community resources, tutorials, or Stack Overflow answers. You will often be reading source code to figure things out. That is fine if you enjoy that, but it slows you down if you just want to get something working.
There is a middle ground worth mentioning. You can export Chance models to other formats or use the sampled outputs in downstream analysis with libraries like crossfilter or d3 for visualization. I built a dashboard once where Chance handled the Bayesian updating and D3 rendered the posterior distributions in real time. It worked well, and the browser execution was actually one of the stronger points of this tool.
