[PROJ] proj.js: JavaScript bindings for PROJ - both Node.js native & browser WASM

Will Cohen wwcohen at gmail.com
Sun Jan 4 10:32:43 PST 2026


Very cool!

I’m still tidying it up but I think I’ll have an (asynchronous) solution
using workers that uses those emscripten fetch calls, that doesn’t need
COOP/COEP, for
https://github.com/willcohen/clj-proj. I’m still doing a touch of debugging
but hope to cut a new release in the next week. Assuming it works, you
should feel free to reimplement!

Will

On Sun, Jan 4, 2026 at 1:27 PM Momtchil Momtchev via PROJ <
proj at lists.osgeo.org> wrote:

> There is indeed no solution for curl in WASM, so the network must be
> reimplemented. This is what I meant when I said that there were people
> working on this and that I was going to integrate their work.
>
> However, currently, enabling pthread support in emscripten results in a
> WASM binary that must have COOP/COEP enabled to work and this restriction
> will be passed on to any user website that uses PROJ.
>
> Many low-end hosting providers do not support this. For example, Github
> Pages does not allow it.
>
> There is a trick with a service worker that allows to manually override
> the flag, but this also adds a very impractical layer to every user of the
> library.
>
> When PROJ 9.8.0 is released, with this feature, I will certainly integrate
> it in the WASM bindings, but I am still not very sure how. I will probably
> have two builds, one in which the WASM can be used as a normal JavaScript
> npm module without any restrictions, and one which has the network
> capability, but adds a restriction that will be passed down to every user
> and website that uses PROJ.
>
> The current situation with SharedArrayBuffer is the result of the
> mitigation of a very serious security flaw (side-channel timing attacks -
> such as Meltdown and Spectre) and was introduced as an immediate solution
> in order to block these attacks. Ever since there have been discussions
> about bringing it back with some kind of security. Should this happen,
> shared memory multithreading will once again be freely available in WASM
> for everyone.
>
> On 04/01/2026 17:39, Javier Jimenez Shaw wrote:
>
> Hi.
>
> You mention that there is no solution for curl in wasm.
> Since this PR https://github.com/OSGeo/PROJ/pull/4627 (in master, not
> released yet) you can do network requests. You have to enable the proper
> compilation flag.
>
> The js function, as explained in the PR, has to be called in a worker
> (thread). That is an emscripten limitation.
>
> There is an example in
> https://jjimenezshaw.github.io/wasm-proj/example.html
>
>
> I hope projinfo will be available soon as well.
>
>
> On Sun, 4 Jan 2026, 17:21 Momtchil Momtchev via PROJ, <
> proj at lists.osgeo.org> wrote:
>
>> I am excited to announce the public availability of what should be a
>> usable beta version of proj.js - JavaScript bindings for PROJ.
>>
>>
>> https://github.com/mmomtchev/proj.js
>>
>> https://www.npmjs.com/package/proj.js
>>
>>
>> proj.js is a dual-environment npm package that works both in the browser
>> (compiled to WASM) and in Node.js (compiled as a native module for
>> Linux, Windows and macOS).
>>
>> It exports both the new C++ API and the older C API to JavaScript in two
>> separate modules.
>>
>> The package is bundler-friendly and leverages Node.js 16 exports to
>> automatically load either the native version or the WASM version. It
>> comes with prebuilt binaries for WASM, Linux x86, Windows x86, macOS x86
>> and macOS arm8.
>>
>> Currently the only documentation are the unit tests and the TypeScript
>> definitions. All methods are covered by TypeScript definitions which can
>> be used as online help in IDEs that parse them. With very few
>> exceptions, all JS methods match the C and C++ API 1:1.
>>
>> This is a new generation of C/C++ to JS project that leverages three new
>> important technologies in the JavaScript world:
>> * SWIG JSE which renders possible the automatic generation of high
>> quality native-feel wrappers with minimal code (2000 lines of SWIG code
>> for 200k lines of C/C++ code, an impressive 1:100 reduction)
>> * emnapi which renders all Node-API modules compatible with WASM using
>> the same API
>> * hadron which renders possible the cross-platform compilation of
>> complex C/C++ projects for JavaScript
>>
>> The whole project is entirely synchronous JavaScript on purpose - most
>> of the methods are fast enough to be used on the main loop and adding
>> async support - which is a simple flip-switch in SWIG - would add a very
>> restrictive requirement to the WASM module -
>> https://web.dev/articles/coop-coep - that is best avoided unless there
>> is a good reason for it.
>>
>> The current version is available on npm and should be more or less
>> usable. The unit testing is somewhat incomplete, but the nominal
>> codepath of all SWIG typemaps have been tested at least once on each
>> platform, including an ASAN build.
>>
>> Currently the main issue is the size of the WASM bundle which renders it
>> impractical for most websites. Currently, the absolute minimum is about
>> 1.2MB w/o libtiff, w/o proj.db, after compression and using only the C
>> API. There are various options for optimising this size, but bear in
>> mind, that proj.js will always be significantly larger than proj4js.
>>
>> This project, together with magickwand.js (ImageMagick for JS) - which
>> is my basic tutorial, will be part of the SWIG JSE tutorials. proj.js is
>> about advanced SWIG JSE techniques - the C++ API contains many modern
>> C++>=11 features and expressing the C API in a garbage-collected
>> language is not very straightforward. magickwand.js has a 1:400 code
>> reduction ratio.
>>
>> You should know that I am not a very advanced PROJ user and my main
>> interest is SWIG (though I am a user), but:
>>
>> * All stability problems, including memory leaks, will be thoroughly
>> investigated, in the limits of what my current access to hardware allows
>> * If there are methods that are incorrectly wrapped, I will fix them
>> * I will fix bundler problems, this is something that is expected to
>> work well, I currently have examples/testing set for the major bundlers
>> such as webpack, vite, rollup and the now obsolete create-react-app
>> * I do not plan to re-implement any of PROJ’ missing features in WASM -
>> mainly the file and the network API - but if someone else does (I saw
>> there are people working on it), I will integrate it
>> * I do not plan to work on reducing PROJ’ own size, but I may eventually
>> add emscripten split module support in order to reduce the initial bundle
>>
>> The current beta:
>>
>> * WASM must be built with emscripten 4.0.8
>>
>>     https://github.com/mmomtchev/hadron/issues/79
>>
>>     Will be fixed in the next hadron release.
>>
>> * Leaks memory if loaded/unloaded repeatedly in a Node.js worker_thread
>>
>>     https://github.com/nodejs/node/issues/45088
>>
>>     As the root cause is in Node-API itself, this won't be fixed in the
>> near future, I am looking at alternative solutions. Currently every time
>> you create a worker_thread that uses proj.js, when it quits, part of the
>> memory is not freed until the main thread exits.
>>
>>
>>
>> --
>> Momtchil Momtchev <momtchil at momtchev.com>
>>
>> _______________________________________________
>> PROJ mailing list
>> PROJ at lists.osgeo.org
>> https://lists.osgeo.org/mailman/listinfo/proj
>>
> --
> Momtchil Momtchev <momtchil at momtchev.com> <momtchil at momtchev.com>
>
> _______________________________________________
> PROJ mailing list
> PROJ at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/proj
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/proj/attachments/20260104/c67b4047/attachment.htm>


More information about the PROJ mailing list