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

friendly_iframe

v1.0.1

Published

Load a script inside of a friendly iframe with a surface API

Readme

friendly_iframe

create a friendly iframe with an API run on the parent.

Iceberg loading.

The friendly iframe can be used to load iceberg code onto the page. This is code that we want to run inside of the iframe, but we want to provide a surface API that it can use to work with the parent frame.

surface.js:

const $ = require('jquery');
const fif = require('friendly_iframe');

// Load the rest of the code.
fif('js/iceberg.bundle.js', {
  $: $
});

The Embeded Problem

When creating a library or component that is loaded onto other people's pages, we have to be careful to not break anything else that might exist on the page, and to prevent things on the page from affecting our code.

The friendly iframe allows us to load most of our code in an iframe, where we can control every library on the page. This even protects us from hacks that change the native library.

Real world example.

At Tout we had an issue with a page that used an old library scriptaculous. This issue is that this library implements it's own Object.keys() method that does not use hasOwnProperty. This resulted in the ToutPlayer not working because Object.keys would walk up the prototype and return unexpected results.

Our code was already wrapped in an IIFE by webpack. This provides a lot of protection and allows us to safely use our version of jQuery. But it doesn't protect us from changes to that native library.

The first option might be to stop using Object.keys() and instead use something like lodash or underscore. The issue is that these libraries use a polyfill for native functions like Object.keys(). This means that they will use the broken version when loaded with a library like scriptaculous.

Our best hope is Iceberg loading. In this process we have two Javascript files. surface.js and iceberg.js.

surface.js is an IIFE that contains everything we need to manipulate the page. This is our risk surface. It will still get broken or hacked native functions on the page. But we can make surface as small as possible.

iceberg.js is the rest of our code. It doesn't matter if it is IIFE or not, because it is the only script in the iframe. The risk is reduced to just iframe origin issues. And since it's a friendly iframe, the origin is already set to the page.