npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

svelte-mainloop

v1.2.2

Published

[![npm version](https://badge.fury.io/js/svelte-mainloop.svg)](https://badge.fury.io/js/svelte-mainloop) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

Readme

Svelte-MainLoop

npm version License: MIT

1.2.0 update: introduces Attachments for setting up HTML Canvas. Hook up your draw function, run an init function and even keep the canvas scaled to its container, all with {@attach ... } call.

Refer to the below Svelte Playground for instructions on how to use.

Svelte Playground


A svelte wrapper for mainloop.js that handles function registration and cleanup, and lets you join and leave the loop with a single component. It also provides some debugging info and tools, exposes all of the standard mainloop.js functionality, is fully typed, and provides inline documentation through intellisense.

Requirements

  • Svelte
  • Browser environment with requestAnimationFrame support. If you're running node, try using mainloop.js directly.
  • If you're running SvelteKit, svelte-mainloop will provide a dummy loop for ssr, and should run correctly on the client side.

Getting Started

First, install svelte-mainloop:

npm install svelte-mainloop

Then import the JoinLoop component, write your update function (this will get called each frame, basically) and pass update to JoinLoop:

<script>
   import { JoinLoop } from 'svelte-mainloop'

   function update() {
      // do something
   }
</script>

<JoinLoop {update} />

Try it on the Svelte Playground

That's literally all you need to do to get moving, but svelte-mainloop has a lot more functionality.

For starters, MainLoop gives you 4 different stages of the loop to tap into, which are used for various purposes. Each stage uses a callback that is slightly different, with different arguments. The most common one, and the one used above, is update. (the others are begin, draw and end.)

Update accepts delta, which is the time since the last update. You can use this to keep track of the time your app has been running, like so:

<script>
   import { JoinLoop } from 'svelte-mainloop'

   let timeElapsed = $state(0)

   function update(delta) {
      timeElapsed += delta
   }
</script>

{timeElapsed} seconds passed.

<JoinLoop {update} />

IMPORTANT: MainLoop.js by default provides its delta value as the number of milliseconds, so at 60fps the delta is 16.67. Svelte-mainloop divides this by 1000 when passing it to callbacks, in order to express delta in seconds.

If you want to remove your component from the loop, perhaps because it is paused or has completed its task, you can do so by wrapping JoinLoop in an #if block. JoinLoop will handle the cleanup for you.

<script>
   import { JoinLoop } from 'svelte-mainloop'

   const COMPLETION_TIME = 10

   let isPaused = $state(false)
   let timeElapsed = $state(0)

   function update(delta) {
      timeElapsed += delta
   }
</script>

{timeElapsed} seconds passed.

<button onclick={() => isPaused = !isPaused}>{ isPaused ? 'Play' : 'Pause'}<button>

{#if !isPaused && timeElapsed < COMPLETION_TIME}
   <JoinLoop {update} />
{/if}

(You could also check for these and immediately return out of your update function, but doing it this way means that mainloop won't iterate over this component at all if it doesn't have to.)

There are three other stages you can also use: begin, draw, and end.

It's highly recommended to read through the mainloop docs to understand what each stage is used for and what arguments they pass to the callback.

ViewLoop

You can import the ViewLoop component and display it in your app in order to display some information about the mainloop.

<script>
   import { ViewLoop } from 'svelte-mainloop'
</script>

<ViewLoop />

In addition to providing start/stop and reset buttons, ViewLoop displays:

  • The loop's current FPS
  • The current frame (increments with each draw call)
  • The current tick (increments with each update call)
  • Timestamp Time since the app was loaded
  • Last Timestamp (updates when the loop is stopped)
  • Last Absence - the length of time the loop was paused for previously
  • Last Delta - the delta of the last update (expressed in milliseconds here)
  • MainLoop's panic boolean

ViewLoop also displays the number of functions that are registered with each stage of the loop. This can be useful to check if you have a memory leak and are not removing items from the loop when they're done.

Typescript

svelte-mainloop is fully typed and should provide inline help via intellisense. Most of this is taken from the mainloop.js documentation directly.

You can also import the callback function types explicitly using typescript, and type them using arrow function syntax:

<script lang="ts">
   import type { BeginCallback, UpdateCallback, DrawCallback, EndCallback} from 'svelte-mainloop'

   const update: UpdateCallback = (delta: number) => {
      // your code here
   }
</script>

Or if you prefer, you can type the callback functions with jsdoc:

<script>
   // Use this option if you're using vanilla js
   /** @type {import('svelte-mainloop').UpdateCallback} */
   function update(delta: number) {
      prevValue = value;
      value = (value + delta) % max;
   }
</script>
<script lang="ts">
   // use this option if you hate arrow functions
   // using implements - make sure to import the type
   import type { UpdateCallback} from 'svelte-mainloop'

   /** @implements {UpdateCallback} */
   function update(delta: number) {
      prevValue = value;
      value = (value + delta) % max;
   }
</script>

This might be useful if you prefer to use the function keyword. In all three cases, hovering over the UpdateCallback keyword will display intellisense.