Skip to content

Add a Best Practices section to the website. NFC - #27334

Open
sbc100 wants to merge 1 commit into
emscripten-core:mainfrom
sbc100:best_practices
Open

Add a Best Practices section to the website. NFC#27334
sbc100 wants to merge 1 commit into
emscripten-core:mainfrom
sbc100:best_practices

Conversation

@sbc100

@sbc100 sbc100 commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

I've been working on this as part of the https://developer.chrome.com/docs/modern-web-guidance project and it seems like whatever we do there it makes sense to maintain best practices guide directly in emscripten.

@sbc100
sbc100 force-pushed the best_practices branch 3 times, most recently from 7d2220d to 7052085 Compare July 13, 2026 20:30
@sbc100
sbc100 requested review from dschuff and kripken July 13, 2026 20:30
Comment thread site/source/docs/compiling/best_practices.rst Outdated
Comment thread site/source/docs/compiling/best_practices.rst Outdated
Comment thread site/source/docs/compiling/best_practices.rst Outdated
Comment thread site/source/docs/compiling/best_practices.rst Outdated
Comment thread site/source/docs/compiling/best_practices.rst Outdated
Comment thread site/source/docs/compiling/best_practices.rst Outdated
Comment thread site/source/docs/compiling/best_practices.rst
Comment thread site/source/docs/compiling/best_practices.rst Outdated
Comment thread site/source/docs/compiling/best_practices.rst Outdated
Comment thread site/source/docs/compiling/best_practices.rst Outdated
@sbc100
sbc100 force-pushed the best_practices branch 3 times, most recently from f9da982 to 407b7ab Compare July 14, 2026 18:35

@dschuff dschuff left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, I forgot to hit send yesterday.

Comment thread site/source/docs/compiling/best_practices.rst Outdated
Comment thread site/source/docs/compiling/best_practices.rst
Comment thread site/source/docs/compiling/best_practices.rst Outdated
Comment thread site/source/docs/compiling/best_practices.rst Outdated
Comment thread site/source/docs/compiling/best_practices.rst Outdated
Comment thread site/source/docs/compiling/best_practices.rst Outdated

@sbc100 sbc100 left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feedback addressed

Comment thread site/source/docs/compiling/best_practices.rst Outdated
files before linking rather than combining everything into a single monolithic
compiler invocation.
- **Don't rely on raw ``extern "C"`` pointer manipulation** when interacting
with complex C++ objects across the JavaScript boundary; prefer Embind.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This point feels out of place in this list. It is at minimum debatable, I'd say? Raw pointer manipulation is very simple and efficient once you know it.

Generally speaking, I don't think we should recommend embind so generally, given the overhead. It is better that people make the effort to be efficient where it matters, and use embind where speed isn't an issue, but hard to put that into a short bullet point...

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe "perfer embind, unless you really know what you doing" although I'm not sure how to say that exactly either.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's best to leave it out. There isn't a simple-enough best practice to recommend.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what I'm trying to do here is have newcomers avoid trying do direct pointer manipulation, and present embind as the well-lit path to getting nice integration between native and JS code.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My worry is that people start using embind even for simple things that don't need it, and then later ask "wait why is everything so slow?"

I guess I disagree about embind being the well-lit path. Or maybe it is well-lit but has pitfalls 😄

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could it make sense to have a recommendation based on the type of API being exported to JS? e.g. use Embind if you have a C++ API or you want to do X and Y with your interop, or use something else if it's a C API?

@sbc100 sbc100 Jul 20, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps we could phrase it as a warning against direct pointer manipulation unless you have a good reason (and good skills) to go that route.

I'm also thinking if recommending using pointer + subarray when passing data around rather than using a lot of calls. e.g. prefer getBytesFromWasm(ptr) over a sequence of getSingleValueFromWasm()

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rephrased this point and using Avoid .. ; prefer .. rather than being overly prescriptive.

Comment thread site/source/docs/compiling/best_practices.rst Outdated
@sbc100
sbc100 force-pushed the best_practices branch 2 times, most recently from a282780 to b759f99 Compare August 25, 2026 19:44
@sbc100
sbc100 requested a review from kripken August 25, 2026 20:03
@sbc100
sbc100 requested review from dschuff and hoodmane August 25, 2026 20:03
- **Use simple comma-separated lists** for list-based settings (for example,
``-sEXPORTED_FUNCTIONS=_main,_malloc`` rather than JSON arrays like
``-sEXPORTED_FUNCTIONS=['_main','_malloc']``).
- **Avoid long lists on the command line**; Use the ``@filename`` instead (for

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- **Avoid long lists on the command line**; Use the ``@filename`` instead (for
- **Avoid long lists on the command line**; use a response file instead, with ``@filename`` (for

compiler invocation.
- **Avoid direct usage of C/C++ functions from JavaScript**; prefer higher-level
interfaces such as :js:func:`cwrap` and/or :ref:`embind` that support more
than purely numeric types.

@kripken kripken Aug 26, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still disagree with this. Direct usage is simply faster, and often works well. How about

  • Call directly between C/C++ and JavaScript where possible. When only passing around numeric types this is the most efficient thing to do.
  • For more complex things, like passing a std::vector between the languages, use embind.

- **Don't include the "=1" suffix for boolean flags.** For example, write
``-sSTRICT`` and ``-sALLOW_MEMORY_GROWTH`` rather than ``-sSTRICT=1`` or
``-sALLOW_MEMORY_GROWTH=1``.
- **Use separate compilation** by compiling ``.cpp`` sources to ``.o`` object

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would put all the things before this in a "lint" section. Separate compilation and C++/JS interop feel like substantially different things, choices about the build system and design.

payload size is the priority.
- ``-flto``: Enable Link-Time Optimization (LTO) during both the compilation and
linking steps of release builds for maximum runtime performance and size
reduction.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we recommend Closure here?

- ``-flto``: Enable Link-Time Optimization (LTO) during both the compilation and
linking steps of release builds for maximum runtime performance and size
reduction.

@kripken kripken Aug 26, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section overlaps with our Optimizing Code page. Perhaps link to there? Or perhaps have a section here for optimizations that summarizes that page?

In particular, while most of this list is optimizations, things like STRICT feel more like "lint" (group with "avoid -sWASM=1, and EXPORT_ES6 feels more like "design choices" (group with "separate the compile&link stages)

--------------------------------

When exposing C++ functionality to JavaScript, prefer :ref:`embind` (``--bind``)
over raw ``extern "C"`` functions. Embind naturally handles C++ classes,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This overlaps with the above text, and I have the same response.

on Emscripten's virtual in-memory filesystem (``MEMFS`` by default). See the
:ref:`file-system-overview` for an architectural overview.

- Do not assume direct access to the host file system.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't a "best practice" so much as a "how to" - ?

- For small temporary files, ``MEMFS`` is sufficient.
- For persistent client-side data storage across browser sessions, use
asynchronous storage backends such as :ref:`filesystem-api-idbfs` or the
:ref:`Filesystem-API`.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps just link to the main filesystem page for filesystem recommendations? This could also summarize that page, if we want that (if so, perhaps mention WasmFS).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants