dash-splash-plugin
A configurable full-screen startup loading overlay for Dash, packaged as a
Dash Hooks plugin.
Install it to enable the default loading-ui:fade-arc loader automatically, or choose from 530 generated loader
identifiers and presets with shared color, size and playback controls. Native Dash and Dash Ant
Design applications use the same configuration.
Installation
Requires Python 3.9+ and Dash >=4.5.0rc0.
Host applications can use React 18.3.1 or React 19. The plugin bundles a
private React 19 runtime for native animations and never reads or replaces the
host's React/ReactDOM. Animations start before Dash's React finishes loading;
even loading-dev does not require changing the application's React version.
Until the first PyPI release, install from a checkout of this repository:
pip install -e .
Once published, install the pinned release with:
pip install "dash-splash-plugin==0.1.0"
Dash discovers the plugin through its dash_hooks entry point. No explicit
registration, asset copying or index_string replacement is needed to enable
the overlay. Native Ant Design loaders are bundled as separate resources, with no
additional Python component-library dependency.
Quick start
Installing the package is enough for a standard Dash app:
from dash import Dash, html
app = Dash(__name__)
app.layout = html.Main([
html.H1("My Dash app"),
html.P("The startup overlay closes after the initial layout mounts."),
])
if __name__ == "__main__":
app.run(debug=True)
To customize the overlay, call setup() before creating the app:
from dash import Dash, html
from dash_splash_plugin import setup
setup(loader="loading-ui:ring", color="#1677ff", size=32, stroke=3, rate=1.0)
app = Dash(__name__)
app.layout = html.H1("My dashboard")
if __name__ == "__main__":
app.run(debug=True)
The default loader is loading-ui:fade-arc; select it explicitly with setup(loader="loading-ui:fade-arc"). Use setup(loader="antd:spin") to select the four-dot spinner,
setup(loader="loading-ui:text-shimmer", text="Preparing dashboard", font_size=20) for a
text animation, or setup(enabled=False) to disable the plugin.
Dash Ant Design
Dash Ant Design is optional. Install it with pip install dash-ant-design, then
use the Python module dash_antd_components in your layout. The overlay works
with these components automatically; configure it with the same setup() call.
Run the interactive demo
From a checkout of this repository:
uv sync --group dev
uv run python usage.py
Open http://127.0.0.1:5001. Select Library, then search Animation to preview Loading UI or a public component or preset from dash-loading-components. Use Preview color to compare five foreground colors. The Python example below updates with syntax highlighting.
Previews use a white background matching the page and an explicit size=64.
They use the isolated animation runtime and the configured rate and playing
settings. The selectors update only the preview, not the process-wide configuration.
Configuration
setup(**changes) updates an immutable, process-wide SplashConfig.
Use one configuration per Python process; apps in the same process share it.
Select an animation with a single qualified library:name identifier:
setup() # Initially uses loading-ui:fade-arc.
setup(loader="loading-ui:fade-arc")
setup(loader="flicker:mail")
setup(loader="spinners:bar") # No trailing -loader.
loader always includes its namespace; short names and a separate library
argument are not accepted. Omitted settings retain their values. Switching the loader
clears previous loader_options unless new options are supplied in the same call.
Unknown identifiers raise ValueError with nearby suggestions and leave the
current configuration unchanged. The generated LoaderId literal provides IDE completion:
from dash_splash_plugin import LoaderId, setup
loader: LoaderId = "flicker:helix"
setup(loader=loader)
Calling setup() without changes does not reset an existing configuration.
Use reset_config() to restore the defaults. get_config().loader always holds
the complete identifier; there is no separate library configuration field.
| Option | Default | Description |
|---|---|---|
enabled |
True |
Enable index injection. |
theme |
"auto" |
Splash theme policy: "light", "dark", "auto" or "system". |
aria_label |
"Loading" |
Accessible status label. |
z_index |
9999 |
Overlay stacking order. |
background |
#f5f5f5 |
Overlay background in light mode. |
dark_background |
#000 |
Overlay background when the splash resolves to dark mode. |
color |
"#1890ff" |
Default loader foreground in both themes; set a CSS color to override it. |
dark_color |
None |
Dark-mode override; falls back to color, then inherited foreground. |
text_color |
None |
Optional text color; falls back to color, then inherited foreground. |
dark_text_color |
None |
Falls back to text_color, dark_color, color, then inherited foreground. |
loader |
"loading-ui:fade-arc" |
Qualified animation identifier, for example "flicker:helix". |
text |
"Loading" |
Text rendered by loading-ui:text* Loading UI loaders. |
size |
None |
Loaders retain their native geometry (antd:spin: 20px, matching Ant Design Spin medium) unless size is specified. Set a CSS pixel size to override; 0 hides the loader. Text loaders use font_size. |
stroke |
None |
Preserve original borders and SVG strokes. A number overrides supported borders and strokes in CSS pixels; dot, text and filled-shape loaders may have no adjustable stroke. |
rate |
1.0 |
Positive relative animation tempo. 2.0 is twice as fast; 0.5 is half speed. |
playing |
True |
False pauses CSS and SVG animations without hiding the loader. |
font_size |
None |
Font size in CSS pixels for loading-ui:text* loaders; independent of container sizing. |
custom_loader_html |
None |
Trusted HTML replacing the selected loader. |
loader_options |
None |
JSON-safe native wrapper options; explicit options override common settings. |
custom_loader_html is inserted verbatim and must only contain trusted HTML.
Size and animation
Graphical loaders fit their container's longest side to an explicit size, preserving their
aspect ratio. size=None retains each loader's original geometry; size=0 hides the
loader. Text loaders retain their original font size unless font_size is set.
stroke=None preserves the artwork's original borders and strokes.
rate must be a finite positive number. Use playing=False to pause animations
while keeping the loader visible. The size, color, rate and playing
parameter names match dash-loading-components. Its pinned React wrappers,
including their native speed mappings, are reused at build time. Installing its
Python package is not necessary. Native options use its snake_case names.
from dash_splash_plugin import list_libraries, list_loaders, setup
print(list_loaders("loading-dev"))
print(list_libraries())
setup(loader="loading-dev:arc", size=48, loader_options={"easing": "linear"})
setup(loader="gridora:orbit", size=48, loader_options={"grid_size": 5})
setup(loader="flicker:mycelium", size=48)
setup(loader="loadersz:heatmapping", size=96)
The generated registry covers 47 Loading UI components, four antd loaders, and all public
wrappers/presets from 14 dash-loading-components families: loading-dev, ldrs,
spinners, spinners-react, loader-spinner, premium, indicators, m3, epic, flicker,
gridora, loadersz, thinking-orbs and lab. Presets share their component chunk.
list_loaders() and the generated LoaderId literal are the source of truth.
Library and loader names use kebab-case. Trailing -loader is omitted:
for example, use setup(loader="spinners:bar") or setup(loader="flicker:mail").
list_libraries() lists available namespaces. list_loaders() returns qualified
identifiers; list_loaders("flicker") filters them without stripping the namespace.
Every returned identifier can be passed directly to setup(loader=...).
Select the four-dot spinner with setup(loader="antd:spin").
The antd library provides these native React presets:
| Loader | Component |
|---|---|
antd:spin |
Default Spin four-dot indicator. |
antd:loading |
Spin with the rotating LoadingOutlined icon. |
antd:progress |
Active Progress bar, 160px wide, with a fixed 70% animated track. This is a loading illustration, not measured startup progress. |
antd:skeleton |
Active Skeleton with a title and two paragraph rows, 160px wide. |
Choose, for example, setup(loader="antd:skeleton"). All four are
pre-rendered from the native React components at build time into HTML and CSS.
They animate immediately without loading React or a component module at runtime,
follow the splash color, and support size, rate, playing, and reduced motion.
Styles are scoped to each loader's shadow root.
Epic names also omit -spinner: use setup(loader="epic:atom")
or loader="epic:hollow-dots". Suffixed Epic names are not accepted.
All eight Epic presets, 64 Flicker presets (including helix), and the
spinners/spinners-react libraries also use build-time HTML/CSS and animate
without downloading a React runtime. The generated registry determines first-paint support.
When loader_options is supplied, the pre-rendered preview appears immediately,
then the native component mounts with the private runtime to apply those advanced options.
Theme behavior
Choose the splash theme independently of its color values:
theme |
Behavior |
|---|---|
"auto" (default) |
Follow the application's root theme; fall back to light when none is declared. Ignores the system preference. |
"light" |
Always use light colors, regardless of root markers or system preference. |
"dark" |
Always use dark colors. |
"system" |
Follow prefers-color-scheme, regardless of root markers. |
In "auto" mode, a valid html[data-theme="light"] or html[data-theme="dark"]
takes priority over html.dark / html.light. Unrecognized attribute values
fall back to the classes; without a dark marker, the splash is light. Changes
to root markers or the system preference update the appropriate theme mode.
The plugin only styles its overlay and does not change the application's root markers.
For a light-only application, including when the operating system is dark:
setup(theme="light", background="#f3f5f4")
For an application with its own theme switch:
setup(theme="auto", background="#f7f9fc", dark_background="#0b1018")
Initialize root theme markers before Dash mounts, for example with a script in
index_string, so the first paint matches the app. The pre-React splash cannot
infer a theme declared inside a React ConfigProvider. Set theme="system"
explicitly to use the operating system's preference; unlike previous behavior,
"auto" no longer falls back to it.
background / dark_background choose the overlay colors. color / dark_color
choose the loader colors; text loaders support separate text_color /
dark_text_color overrides. All loaders use #1890ff blue by default in both
modes. Pre-rendered markup and styles are embedded in the initial response;
other libraries load their native components from cacheable modules without
waiting for the host React.
Configuration validation
setup() accepts only the current configuration fields listed above. Unknown
options raise TypeError without changing the active configuration. No aliases
or deprecated parameter conversions are provided.
setup(loader="loading-ui:ring", color="#1677ff", size=32, stroke=2)
setup(loader="loading-ui:text-shimmer", text="Loading", font_size=20)
Startup lifecycle
The overlay is injected before React mounts and observes Dash's
#react-entry-point ._dash-loading element. When that element disappears, the
overlay is removed. It does not wait for application-specific background work
or reappear during later callbacks. Use dcc.Loading for callback loading states.
The overlay strictly follows Dash's initial layout mounting. Elapsed time and script loading errors do not dismiss it. Its observer is released when the overlay is removed.
First-paint rendering
With default native options, 97 loaders render directly from HTML/CSS embedded in the response, without downloading animation modules or React:
| Namespace | Pre-rendered identifiers |
|---|---|
antd |
4 |
epic |
8 |
flicker |
64 |
spinners |
12 |
spinners-react |
9 |
Pre-rendered loaders display their build-time HTML/CSS immediately and do not mount a React tree or request animation modules with default options. Other libraries use an inline HTML/CSS fallback only while their selected module loads. Their original React animation mounts immediately in an independent root with Shadow DOM style isolation. Motion components use the real Motion runtime. The main Dash root is never replaced. A failed import or render keeps the fallback. There is no forced minimum display time.
Only the selected module, its stylesheet and shared dependencies are requested.
Assets have content-hashed names and immutable caching. Removing the overlay first
unmounts its React tree and disconnects observers. Delayed imports
cannot remount a dismissed overlay. Reduced-motion preferences pause animations.
Strict Content Security Policy must allow the inline startup script/style and
same-origin module/style resources under _dash-splash-plugin/react/.
Troubleshooting
- After rebuilding or upgrading the plugin, restart the Dash process. A running process caches the resource manifest; old hashed asset URLs may no longer exist.
- For non-pre-rendered loaders, a brief generic spinner while the selected module
downloads is expected. It does not wait for Dash's React. A persistent fallback
indicates an asset or rendering failure; inspect browser errors and requests
under
_dash-splash-plugin/react/. - Invalid loader identifiers fail during
setup()instead of silently selecting another animation. Uselist_loaders()to inspect supported identifiers.
Python API
from dash_splash_plugin import (
LoaderId,
LoaderLibrary,
SplashConfig,
setup,
get_config,
list_loaders,
list_libraries,
reset_config,
)
setup() returns the updated configuration, get_config() reads it, and
reset_config() restores the defaults.
Development
uv sync --group test
uv run pytest -q
To rebuild, run npm ci then uv run python scripts/build_loaders.py.
Frontend rebuilding requires a Git checkout. Python wheels and source
distributions include the Python runtime, prebuilt assets, typing files and
licenses, but exclude scripts/, npm configuration, tests and demo files.
The build fetches exact upstream commits, generates the registry and Python
literal, and bundles native React modules with one shared, private React 19 runtime.
The scripts/react19 workspace isolates these browser runtime dependencies from
the React 18 server-rendering/type baseline. The manifest records upstream React
requirements; the bundled runtime satisfies them without changing the host.
--upstream PATH --loading-ui PATH accepts existing checkouts at those commits.
Run npm run typecheck and npm run test:browser; use ALL_LOADERS=1 npm run test:browser for all 530 choices.
Repeat with REACT_VERSION=19.2.4 to verify isolation from a React 19 host.
Use ALL_LOADERS=1 NO_HOST_REACT=1 npm run test:browser to block the host React
scripts and check that all animations still render.
The browser tests need Playwright Chromium (npx playwright install chromium)
and a Python interpreter with Dash 4.5.0rc2 (set PYTHON to its executable).
Node, npm and the source checkouts are not required by wheel/sdist users.
Development uses Dash 4.5.0rc2. The gallery uses only Dash's built-in controls;
no additional Python component library is needed.
License
MIT. See LICENSE. Bundled third-party licenses, upstream NOTICE and
source revisions ship in dash_splash_plugin/resources/licenses/. The M3 library
retains Apache-2.0 attribution. Excluded upstream libraries and non-open gallery
patterns are not imported.
Metadata
Release files for dash-splash-plugin 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| dash_splash_plugin-0.1.0.tar.gz | 509.1 kB | Without provenance | Details for dash_splash_plugin-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| dash_splash_plugin-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for dash_splash_plugin-0.1.0-py3-none-any.whl |
Total release size: 1.6 MB
Release files / dash_splash_plugin-0.1.0.tar.gz
| Download URL | dash_splash_plugin-0.1.0.tar.gz |
|---|---|
| Size | 509.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f98172dcaa1e8ef0f6953f24d36cb1f9ec3be03ff89c9c50563ee3f6fd4b22a5
|
|
BLAKE2b-256 checksum How to use checksums |
7ea9751090c3a6503075c3443358c36ce88268bab702f6a558b8dc4dda985277
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / dash_splash_plugin-0.1.0-py3-none-any.whl
| Download URL | dash_splash_plugin-0.1.0-py3-none-any.whl |
|---|---|
| Size | 1.0 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
34ea921772f45fbc8f4ea53da8663818e0f00cb502ab6b732405006d0e89ae7d
|
|
BLAKE2b-256 checksum How to use checksums |
620929ff1cef3579892cfce86e8e679dd43ea5d8be8affe4df9ea217a0d1224a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.9.22 {"installer":{"name":"uv","version":"0.9.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for dash-splash-plugin 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.