fxCode
Write the equation. Get working code.
fxCode turns a LaTeX equation into a real, compiled C++ function on CodeCogs — with documentation, an interactive calculator, and a WebAssembly build you can drop into your own site. You write the mathematics once, in the notation you already use, and everything downstream is generated for you.
V = abh → double BoxVolume(double a, double b, double h)
{
return a*b*h;
}
That is the whole idea, but it is not limited to arithmetic. fxCode understands sums, products, limits, derivatives and integrals, and works out for itself whether each one can be solved exactly or has to be approximated numerically.
Step by step
-
Write your equation. Anywhere that produces LaTeX — by hand, in
fxEditor, or from a spreadsheet with fxRender. All fxCode needs is the
markup, for example
V = abhorI = \int_0^1 e^{-x^2}\,dx. -
Submit it to CodeCogs. Either post it to the submission API, or
submit it with
Publish: manualand finish it on the form we hand back. - Add the documentation. Name the result, describe each parameter, give its units and a sensible range. This is what turns a formula into a page somebody else can use — and the range is what gives your calculator a working slider.
- Check it. The submission page shows the generated C++ and a live calculator running the compiled code. If it returns the right number, the submission is sound.
- Collect your code. Download the C++ from the page, or take the WebAssembly build and the two-line embed snippet and put the calculator in your own site. If a page is not what you want at all, the compile service hands you the WebAssembly module and nothing else.
fxEditor and fxRender produce the LaTeX; fxCode takes it from there. In-page “insert equation” integration on CodeCogs itself is still being wired up — for now, paste the markup, or post it to the API.
What fxCode can convert
| Area | Example | Becomes |
|---|---|---|
| Arithmetic and powers | y = ax^2 + bx + c |
a*x*x + b*x + c |
| Roots, constants, Greek | c = \sqrt{a^2+b^2} |
std::sqrt(a*a + b*b) |
| Functions and subscripts | N = N_0 e^{-\lambda t} |
N_0*std::exp(-(lambda*t)) |
| Finite sums and products | S = \sum_{i=1}^{n} i^2 |
a counted loop |
| Infinite series | S = \sum_{k=0}^{\infty} \frac{x^k}{k!} |
summed until the total stops moving |
| Limits | L = \lim_{x \to 0}\frac{\sin x}{x} |
1.0 — solved exactly |
| Derivatives, including partials | y = \frac{d}{dx}\left(x^3 + 2x\right) |
3.0*x*x + 2.0 — differentiated symbolically |
| Integrals | I = \int_0^1 x e^{x}\,dx |
1.0 — integrated by parts |
| Integrals with no closed form | I = \int_{-\infty}^{\infty} e^{-x^2}\,dx |
adaptive quadrature over a transformed range |
| Factorials and binomials | y = n! + \binom{n}{k} |
l2c::fact(n) + l2c::binom(n, k) |
| Several equations at once | d = b^2-4acx = \frac{-b+\sqrt{d}}{2a} |
two functions, emitted in dependency order |
| Equations that need solving | \cos x = x |
a root-finder, since there is no closed form |
What it cannot convert
fxCode refuses anything it cannot represent faithfully. It will not guess, and it will not hand back code that looks plausible but computes something else.
| Example | Why not |
|---|---|
y = \pm x |
Two values, not one. Submit the branch you want. |
A = \begin{bmatrix}a&b\\c&d\end{bmatrix} |
Matrices and vectors are grids, not scalar equations. Refused outright. |
y = \begin{cases} x & x>0 \\ 0 \end{cases} |
Piecewise definitions need a condition language fxCode does not have. |
y = \int e^{-x^2}\,dx |
An indefinite integral with no elementary antiderivative. Give it limits and it becomes a number. |
a = b + 1 with b = a + 1 |
Circular: no evaluation order exists. The loop is named in the error. |
ax + b = c |
Ambiguous — which symbol do you want solved for? Say so with solveFor. |
Two further limits worth knowing. A run of letters is a product, so xy means
x×y; multi-letter names need \text{...}, as in
\text{area} = \text{width}\cdot\text{height}. And slowly converging series are truncated
— \sum 1/k^2 is accurate to about 1×10−5, not to the last bit.
Exact or numerical?
fxCode decides this for every part of an equation separately, so one formula can mix both. Exact is always preferred: it is faster and accurate to the last bit.
| Construct | Exact when | Otherwise |
|---|---|---|
| Derivative | the differentiation rules reach every node | central differences with Richardson extrapolation |
| Integral | an antiderivative is found and both limits are finite | adaptive Simpson quadrature |
| Limit | substitution works, or l’Hôpital’s rule resolves it | Richardson extrapolation |
| Sum / product | the upper limit is finite | accumulated until the total stops moving |
| Implicit equation | never attempted | bracket search, then the Illinois method |
Every symbolic result is checked numerically before it is trusted: an antiderivative is differentiated back and compared against the original integrand, and a symbolic derivative is compared against a central difference. If they disagree, fxCode discards the symbolic result and uses the numerical method instead. The response tells you which was used for each part.
WebAssembly
Every calculator-eligible function on CodeCogs is also compiled to WebAssembly. That build runs in the visitor’s browser — once the module has loaded there is no server involved at all, so a slider can redraw a curve as fast as you can drag it, and your page keeps working whether or not CodeCogs is reachable.
The easy way: two lines
Paste this into any page. The script is loaded once, then initialises every .codecogs-embed element it finds.
<div class="codecogs-embed" data-module="359" data-anchor="fn-rosin-cdf" data-mode="graph"></div>
<script src="https://codecogs.com/assets/js/fxgraph.js"></script>
Every calculator on the site has an Export panel that writes this snippet for you, with the values you currently have on screen already baked in. The attributes it uses:
| Attribute | Meaning |
|---|---|
data-module | the page’s module ID |
data-anchor | which function on that page, e.g. fn-rosin-cdf |
data-mode | calculator for the full input panel, graph for a fixed plot with an Edit button |
data-p0, data-p1, … | starting value for each parameter, in signature order |
data-range-index | which parameter is swept along the x-axis (graph mode) |
data-lower, data-upper, data-points | the sweep |
data-y-scale | log for a logarithmic y-axis |
data-animate-index, data-animate-start, data-animate-end, data-animate-step | animate a second parameter, sweeping it repeatedly |
data-key | the key that unlocks a locked module |
Everything else the widget shows — parameter names, units, descriptions, example values — it reads from the module itself.
The raw way: call the module yourself
If you would rather not use our widget, fetch the WebAssembly module and call it directly. It has no imports and exports a single entry point, cc_compute.
const res = await fetch('https://codecogs.com/calc/359/fn-rosin-cdf/wasm');
const { instance } = await WebAssembly.instantiate(await res.arrayBuffer(), {});
// WASI reactor modules expose this; call it once if present.
instance.exports._initialize?.();
// Arguments are the function's parameters, in signature order.
const y = instance.exports.cc_compute(1, 2, 0.5);
The module also describes itself: info() returns a pointer to a JSON string (read it as below; do not free it) giving the function’s name and, for each parameter, its name, units, description, example value and whether it is text.
The module is served with a long-lived ETag and immutable caching, so a repeat visitor pays for it once.
Numbers cross the boundary natively as double. Strings need marshalling, because WebAssembly only understands numbers and pointers — the module exports malloc, free and its memory for exactly this:
function writeString(e, str) {
const bytes = new TextEncoder().encode(str + '\0');
const ptr = e.malloc(bytes.length);
new Uint8Array(e.memory.buffer, ptr, bytes.length).set(bytes);
return ptr; // free() it when the call returns
}
A function that returns a string hands back a pointer you must read up to the first zero byte and then free. These modules are compiled without growable memory, so every allocation must be released — a page that leaks them will eventually run out.
Interactive calculators
Three endpoints back every calculator on the site. They send permissive CORS headers, so you can call them from your own pages. All of them are plain GETs.
| Endpoint | Returns |
|---|---|
/calc/{module}/{anchor}/meta | the parameter list: name, type, description, units, example value and default range |
/calc/{module}/{anchor} | one computed value, or a set of points when a range is given |
/calc/{module}/{anchor}/wasm | the WebAssembly build |
Building the query yourself
Parameters are passed positionally as p0, p1, … in signature order — not by name, so that a renamed parameter never silently changes what a saved link computes.
# a single value: a=2, b=3, h=4
/calc/1452/fn-boxvolume?p0=2&p1=3&p2=4
# sweep the first parameter from 10 to 20 in 50 steps, holding the rest
/calc/1452/fn-boxvolume?range=0&lower=10&upper=20&points=50&p1=3&p2=4
range is the index of the parameter to sweep; it must be one meta reports as
rangeable. points is between 2 and 500. A single value comes back as
{"value": "24"}; a sweep as {"points": [{"x": …, "y": …}, …]}.
The meta response is what our own interface is built from, so anything we can render, you can render:
{
"moduleId": 1452,
"anchor": "fn-boxvolume",
"fnName": "BoxVolume",
"params": [
{ "name": "a", "type": "double", "uiKind": "number", "rangeable": true,
"description": "length of box", "units": "m",
"exampleValue": "10:20", "rangeDefault": { "lower": "10", "upper": "20", "points": 50 } }
]
}
For anything interactive, prefer the WebAssembly route: the compute endpoint costs a round trip per point, while the module computes locally for nothing.
Two services
fxCode offers two ways in, and which you want depends on whether you are publishing or building.
| Compile | Submit | |
|---|---|---|
| Endpoint | POST /fxcode/compile | POST /fxcode |
| You get | a WebAssembly module on our CDN | a published page on CodeCogs |
| Creates a page? | no | yes |
| Identified by | your email and public key | a CustomerToken |
| Use it when | you want the maths running in your own product | you want to share the result with others |
The compile service
Post an equation, get back a WebAssembly module built for you alone. Nothing is published and no page is created — this is a build service.
| Field | Required | Meaning |
|---|---|---|
email | yes | the account the public key belongs to |
publicKey | yes | your fxCode public key, e.g. fx_pk_2pjy6pxke |
latex | yes | the equation, e.g. V = abh |
units | units per symbol, e.g. {"a": "m", "b": "m"}. An equation alone does not say whether a is metres or seconds, so if you know, tell us and we will hand it back with the parameters |
curl -X POST https://codecogs.com/fxcode/compile \
-H 'Content-Type: application/json' \
-d '{
"email": "[email protected]",
"publicKey": "fx_pk_2pjy6pxke",
"latex": "V = abh",
"units": { "a": "m", "b": "m", "h": "m" }
}'
{
"uniqueID": "a4743467fbee0613f6e9543762b1cd2dba3970bef0c41851088a81615e4395d8",
"wasm": "https://fxcode.codecogs.com/module/a4743467….wasm",
"entryPoint": "cc_compute",
"key": "fx_pk_2pjy6pxke",
"parameters": [
{ "name": "a", "type": "double", "units": "m" },
{ "name": "b", "type": "double", "units": "m" },
{ "name": "h", "type": "double", "units": "m" }
],
"method": "direct evaluation"
}
method tells you whether your equation is computed exactly or approximated — see Exact or numerical? above. Parameters are listed in the order cc_compute takes them, and are always double: there is no route from a LaTeX equation to a string-valued function.
The call is idempotent. The same equation from the same key returns the same uniqueID and the same URL without rebuilding, so you can call it on every deploy without thinking about it.
Fetching your module
wasm is served by fxCodeServer, the same compiler every calculator on this site uses, and it is locked to your key: fetching it plainly gets a 403, not a module. Present key either as a query parameter or as a header:
fetch(wasmUrl + '?key=' + encodeURIComponent(key))
// — or —
fetch(wasmUrl, { headers: { 'X-Fx-Key': key } })
There is no separate unlock step once you have the bytes — the module you get back computes real values straight away:
const res = await fetch(wasmUrl + '?key=' + encodeURIComponent(key));
const { instance } = await WebAssembly.instantiate(await res.arrayBuffer(), {});
instance.exports._initialize?.();
const volume = instance.exports.cc_compute(2, 3, 4); // 24
| Export | Purpose |
|---|---|
cc_compute(double, …) | the equation, one argument per parameter in the order listed above |
cc_compute_range(index, lo, hi, n, …) | sweeps one parameter across a range in one call, for plotting a graph without one request per point |
What the lock is, and what it is not
Be clear-eyed about this. The check happens once, on the request that fetches the module — there is nothing compiled into the module itself any more, no watermark and no embedded key. That means a module already sitting in a visitor’s browser cache, or saved to disk by anyone who legitimately fetched it, has no lock in it to strip: the protection is entirely about who can download a copy in the first place, not about what happens to one afterwards. Treat your key as a bearer credential worth protecting — anyone holding it can fetch your modules — and do not embed it in a public client-side bundle if that is a real concern for your integration.
Your keys
Every account gets a key pair when it is created. The public key is yours to use — it travels in request bodies and is what you present when fetching a module, so treat it as a credential, not as something to publish. The private key stays with us and proves the request to build a module in the first place is really from your account.
Keys are short enough to paste into a config file: fx_pk_ plus nine characters, drawn from an alphabet with no i, l, o, u, 0 or 1 so they survive being read off a screen. Ask us for yours.
Resetting a key pair does not by itself change access to a module already built — each build was locked to the exact key presented at the time. Rebuild anything you want locked to the new key.
Errors
| Status | Meaning |
|---|---|
400 | a field is missing or malformed — errors lists every problem at once |
401 | that email address and public key do not match an account |
422 | the equation could not be converted; the message says why |
502 | it converted, but the build service could not compile it |
The submission API
Post one JSON object to https://codecogs.com/fxcode. This is the only write path on CodeCogs that does not need a browser session, so it authenticates with a token of its own.
| Field | Required | Meaning |
|---|---|---|
CustomerToken | yes | identifies you as the author |
LaTeX | yes | the equation, e.g. V = abh |
Name | what the equation returns. Also names the generated function. Taken from the equation’s left-hand side if omitted | |
Visibility | public, protected (your organisation) or private. Defaults to private | |
Tag | where it is filed, e.g. Maths/Harmonics/SoundVibrations | |
Brief | one line, shown in search results | |
Detailed | the full description; LaTeX is fine in here | |
Parameters | [["a", "length of box", "m", "10-20"], …] — symbol, description, units, range | |
Units | the units of the result | |
Publish | automatic (default) publishes it; manual keeps it as a private draft and returns a link to the submission form |
curl -X POST https://codecogs.com/fxcode \
-H 'Content-Type: application/json' \
-d '{
"CustomerToken": "…",
"Visibility": "public",
"Name": "BoxVolume",
"Tag": "Maths/Geometry/Solids",
"Brief": "Volume of a rectangular box",
"Parameters": [["a","length of box","m","10-20"],
["b","width","m",""],
["h","height","m",""]],
"Units": "m^3",
"LaTeX": "V = abh",
"Publish": "automatic"
}'
{
"moduleID": 1452,
"cppState": "compiled",
"name": "BoxVolume",
"tags": ["Maths", "Geometry", "Solids"],
"parameters": [
{ "name": "a", "description": "length of box", "units": "m", "range": "10:20" },
{ "name": "b", "description": "width", "units": "m", "range": "" },
{ "name": "h", "description": "height", "units": "m", "range": "" }
],
"visibility": "public",
"url": "/library/maths/geometry/solids/boxvolume",
"published": true,
"submitUrl": null,
"warnings": []
}
cppState | Meaning |
|---|---|
notpossible | the equation could not be converted. The page still exists, with your mathematics and description on it — there is simply nothing to execute |
converted | C++ was generated, but has not been proved to build |
compiled | generated and compiled cleanly. This is the only state that guarantees a calculator and a WebAssembly build |
A name already in use gets a number appended, so the name you get back may not be the one you sent. Anything fxCode wants to tell you — a parameter you described that is not in the equation, a compile failure — comes back in warnings rather than failing the request.
Asking about a page
GET /fxcode/{moduleID} returns exactly the same object for any page on CodeCogs, whether or not it was submitted this way. Private and protected pages are only described to those allowed to see them; identify yourself with an X-Customer-Token header.
Errors
| Status | Meaning |
|---|---|
400 | the request was malformed — errors lists every problem at once |
401 | the CustomerToken was not recognised |
403 | that page is not visible to you |
404 | no such module |
201 | created |
Getting a token
Tokens are issued per account and are only ever shown once — we store a hash, never the token, so a lost one is revoked and replaced rather than looked up. Ask us for one and tell us what you are building.
CodeCogs®