Hello.

I am Paul Kinlan.

I lead the Chrome and the Open Web Developer Relations team at Google.

Custom Elements: an ecosystem still being worked out

Reading time: 9 minutes

Web Components, specifically Custom Elements, offer exciting possibilities for web development. However, the current ecosystem is still evolving and has potential downsides. The practice of namespacing custom elements (e.g., <amp-*>, <iron-*>) creates "walled gardens" that can lock developers into specific frameworks. While understandable in the early stages, this approach hinders interoperability and leads to duplicated functionality. Ideally, we should move towards a shared vocabulary of elements (like <aspect-image>) where developers choose the implementation, not the vendor-specific element name. This requires a standardized process for defining element names, interfaces, and functionality. Imagine a world where component creators define the contract (e.g., class ShareButton extends HTMLElement { ... }) and users choose their preferred implementation. This model puts developers in control and fosters a more open and interoperable web. Furthermore, meta platforms (like Facebook or WeChat) could play a role by intercepting customElements.define calls and replacing JavaScript elements with native implementations when possible. This approach requires careful consideration, but it could lead to a more streamlined and integrated user experience. Read More

I lead the Chrome Developer Relations team at Google.

We want people to have the best experience possible on the web without having to install a native app or produce content in a walled garden.

Our team tries to make it easier for developers to build on the web by supporting every Chrome release, creating great content to support developers on web.dev, contributing to MDN, helping to improve browser compatibility, and some of the best developer tools like Lighthouse, Workbox, Squoosh to name just a few.

I love to learn about what you are building, and how I can help with Chrome or Web development in general, so if you want to chat with me directly, please feel free to book a consultation.

I'm trialing a newsletter, you can subscribe below (thank you!)

Measuring the impact of autofill on your forms

Reading time: 4 minutes

Measuring the impact of autofill is crucial. In WebKit/Blink browsers, the -webkit-autofill pseudo-class helps track autofill, but it's not supported in Firefox. I've found a workaround in Firefox using the input event, checking for the absence of keyboard interaction. Ideally, a standardized :autofill pseudo-class and a dedicated onautocomplete event would simplify this process, allowing developers to measure and manage autofill effectively. Read More

Some thoughts on the microbit

Reading time: 4 minutes

I gave my son a micro:bit for his birthday, hoping to introduce him to programming. While he preferred FIFA, I ended up having a blast exploring the device myself. I found it incredibly easy to use and a perfect starting point for hardware and software programming. I even coded a (buggy) Breakout clone to test its capabilities! While the web editor is excellent, I believe integrating WebUSB for direct deployment and improving debugging capabilities would greatly enhance the experience. Read More

Waiting for an element to be created

Reading time: 2 minutes

In my quest to understand how to detect when a field has been autofilled, I needed a way to monitor the events of an element that doesn't exist yet. I created a helper function, waitForElement, that uses MutationObserver to wait for an element with a specific ID to be added to the DOM. Once the element is added, the promise resolves and returns the element. This, combined with my previously created monitorEvents function, allows me to start logging events on dynamically created elements, getting me closer to solving the autofill detection puzzle. Read More

Monitor all Events on an Element

Reading time: 1 minute

I needed to figure out how to monitor events on an element (like when a field is autofilled) and Chrome DevTools has a monitorEvents function, but Firefox doesn't. Since I couldn't find an equivalent in Firefox DevTools, I created my own JavaScript function that iterates through an element's properties, finds event listeners (e.g., "onclick"), extracts the event name (e.g., "click"), and attaches a console logger to each event. The code snippet and a corresponding gist are provided. Read More

Simple sharing on the web with navigator.share

Reading time: 2 minutes

I'm excited to share a new, simple API for sharing on the web called navigator.share! It's available in Chrome Dev Channel on Android and allows websites to connect with native apps for sharing. This is a step towards a better inter-app communication system, simplifying sharing and potentially extending to other app interactions. You can try it now on my blog by clicking the share button. I've updated my blog to use it, falling back to my existing solution if the API isn't available. Check out the ChromeStatus page and other linked resources for more information and give us feedback! Read More

Use-cases for sockets API on the web

Reading time: 2 minutes

There's a growing interest in using socket APIs directly within web browsers for various applications, both client-side and server-side. This post lists potential use-cases for outgoing and incoming socket connections, eliminating the need for proxying through web servers. Examples include email clients connecting directly to IMAP/POP3/SMTP, SSH/RDP clients, real-time communication tools like IRC and XMPP, P2P applications like BitTorrent, and direct connections to servers for various purposes like video streaming, Bitcoin, and game multiplayer functionality. For incoming connections, use-cases include hosting servers for many of the aforementioned services (IRC, BitTorrent, HTTP) directly within the browser. Read More

The Headless Web

Reading time: 18 minutes

Do we need a browser in the future? Read More

Automating Android screen recording and device framing

Reading time: 3 minutes

In a previous post, I discussed screen recording from Android. This post details how I automated the process of adding a device frame to those recordings, making them look more professional. Previously, this was a tedious manual process involving Screenflow, but now I've automated it using ffmpeg. The ffmpeg command scales the screen recording and overlays it onto a background image of a device frame. The code, available on GitHub, handles the entire process, including setting up the Android device for recording, pulling the recording, and applying the frame. While the current solution works well, I'm open to suggestions for improvement from ffmpeg experts. Read More

The Lumpy Web

Reading time: 9 minutes

Wrinkles, Crinkles and lumpy bits. Read More

Thoughts on the Credential Management API

Reading time: 3 minutes

Tired of typing in usernames and passwords? So are your users. Autofill helps, but the Credential Management API gives developers more control. It lets you securely store and retrieve user credentials, simplifying logins with just a couple of taps. This Chrome-only API allows access to a PasswordCredential object, rather than raw passwords. It works with other improvements like proper autofill fields (email, username, new-password, current-password) and offers a potential future where landing and login pages are obsolete. Imagine a web where users stay logged in seamlessly, only re-authenticating when necessary. This post covers how to implement the API, including a demo and sample code. Plus, explore how it might combine with the Web Payment Request API to streamline e-commerce. Read More

An organizer's perspective on Progressive Web App Dev Summit

Reading time: 8 minutes

TL;DR - Went well. Lots to learn. Read More

Ephemeral social or content networks

Reading time: 4 minutes

If there is no one around to read your tweet, does it make a difference? Read More

Testing Podcast

Reading time: 1 minute

I've successfully integrated WebTorrent streaming and bit torrent URLs into my blog! This allows me to distribute content like this test podcast without relying solely on my website's bandwidth. It uses the WebSeed BEP, meaning my site acts as a permanent, unchocked seed. I'm excited to experiment further with this tech and explore analytics tracking. Read More

My blog's Service Worker and Caching Strategy

Reading time: 3 minutes

This blog post discusses the implementation of a Service Worker for my blog, with a focus on the caching strategy. I've chosen a "Stale While Revalidate" approach, which prioritizes speed and resilience. The Service Worker intercepts network requests and serves cached content if available, while simultaneously fetching updated content in the background. This ensures the latest version is available after one refresh. The post also details the requirements considered when choosing this strategy, including development simplicity and compatibility with the existing hosting setup (Hugo and NGINX). The provided JavaScript code snippet demonstrates the Service Worker implementation. Read More

Serverless Data Sync in Web Apps with Bit Torrent

Reading time: 7 minutes

This post explores using WebTorrent for serverless data synchronization in web apps, demonstrated by modifying the Voice Memos PWA. The goal was to enable data sharing between devices without a backend server. The solution involves generating magnet URLs that allow peer-to-peer data transfer via WebTorrent. The demo app allows recording audio, saving it locally, and generating a shareable magnet link for access on other devices. This approach offers an interesting alternative to traditional client-server models, especially for scenarios where scalability and serverless operation are desired. Read More

Notification test page

Reading time: 1 minute

Feel free to ignore. Read More

What were the UX issues with Web Intents?

Reading time: 6 minutes

This post revisits the UX issues that contributed to the demise of Web Intents. We never adequately addressed the wide array of potential actions and data types, leading to a generic and confusing user experience. Handling data return from a long-running operation in another app proved problematic, especially if the initiating app closed. The lack of an explicit API for expecting returned data, similar to Android's startActivityForResult, further hindered the development of intuitive UI affordances. The open nature of Web Intents resulted in a proliferation of schemas and protocols, making standardization difficult. Users were forced to choose an app for every action, and developers lacked control over how apps launched, leading to inconsistent experiences. Finally, the absence of reliable fallbacks for unsupported intents eroded developer confidence and potentially left users stranded. In short, a combination of UX shortcomings ultimately led to Web Intents' downfall. Read More

Inline web-page Android intent fallback detection

Reading time: 2 minutes

This post explores how to use Android Intents to detect if a native app is installed. This technique is useful for web apps that also have a native app version, especially for managing push notifications. It allows developers to seamlessly redirect users to the app if it's installed or fall back to the web experience. The method involves creating a special intent URL that opens the app if present, or redirects to a specific URL with a hash fragment. By monitoring the hash change in the browser, the web app can detect if the app launch failed and proceed with web-based push notification registration. While helpful, this approach highlights the complexity of managing push notifications across web and native apps, reinforcing the argument for web-only solutions. Read More

Every browser should support a style of 'intent:' URL syntax

Reading time: 9 minutes

Custom URL schemes for launching apps have limitations: single app handling, one-way data flow, lack of fallback, and limited mobile support. A better approach is needed, one that offers user choice, developer fallback, diverse data transport, web app registration, and online/offline functionality. Android's 'intent:' URL syntax offers a good starting point, abstracting service discovery and supporting fallback URLs. I propose exploring a new 'action:' scheme or 'web+action' to bridge web and native apps, providing a unified service resolution and registration system for a richer, more integrated user experience. Read More