# Pre-EEP: BEAM-level in-app export visibility

**URL:** <https://erlangforums.com/t/pre-eep-beam-level-in-app-export-visibility/5640>\
**Category:** Proposals: RFC\
**Tags:** erlang\
**Created:** [May 19, 2026, 1:27pm UTC](https://erlangforums.com/t/pre-eep-beam-level-in-app-export-visibility/5640 "2026-05-19T13:27:23Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![happi](https://erlangforums.com/user_avatar/erlangforums.com/happi/32/1963_2.png) [@happi](https://erlangforums.com/u/happi)\
**Post date:** [May 19, 2026, 1:27pm UTC](https://erlangforums.com/t/pre-eep-beam-level-in-app-export-visibility/5640/1 "2026-05-19T13:27:23Z")

</div>

I have opened a draft EEP for application-scoped function visibility in Erlang:

> <https://github.com/erlang/eep/pull/85>
>
> This PR proposes application-scoped function visibility for Erlang by adding \`-a…pp/1\` and \`-app\_export/1\` module attributes with BEAM runtime enforcement.\\n\\nThe goal is to provide a package-private-style boundary for functions that are exported for use inside one application but are not public API for external callers.\\n\\nThe draft includes semantics for remote calls, \`apply/3\`, remote funs, distributed calls, hot code loading, backwards compatibility, security considerations, prior art from EEP 5/67, and implementation notes.\\n\\nA prototype has been used to validate the basic design, but a clean public implementation fork will be linked later.

The proposal adds two module attributes:

```erlang
-app(my_app).
-app_export([internal_helper/1]).

```

A function listed in -app\_export/1 remains exported, but the BEAM only allows calls to it from modules declaring the same -app/1 value. Calls from modules in other app domains raise badappcall.

The motivation is to make internal APIs explicit and enforceable without adding new syntax or changing existing modules. This is related to EEP 5 and EEP 67, but differs by proposing runtime enforcement rather than only static or documentation-based visibility.

This is not intended as a security sandbox. A module can explicitly declare an app visibility domain, so the boundary is about encapsulation and accidental use, not preventing malicious code loaded into the node.

I am especially looking for feedback on:

- whether -app/1 is the right attribute name, or whether it risks confusion with OTP application metadata;

- whether explicit module metadata is preferable to deriving visibility from OTP application layout or code paths;

- whether runtime enforcement is desirable for this boundary;

- whether badappcall is the right error shape; and

- whether the VM/JIT cost is acceptable if unrestricted exports keep the hot path to a predictable flag check.

A prototype exists, but I am preparing a clean public implementation fork separately. For now I would like feedback on the design and semantics.
