• DocsDocs
  • PricingPricing
Book a demo
Sign in
Sign in
Book a demo
    • Ready-made features
      • AI Copilots
        AI Copilots

        In-app AI agents that feel human

      • Comments
        Comments

        Contextual commenting

      • Multiplayer Editing
        Multiplayer Editing

        Realtime collaboration

      • Notifications
        Notifications

        Smart alerts for your app

      • Presence
        Presence

        Realtime presence indicators

    • Platform
      • Monitoring Dashboard
        Monitoring Dashboard

        Monitor your product

      • Realtime Infrastructure
        Realtime Infrastructure

        Hosted WebSocket infrastructure

    • Tools
      • Examples

        Gallery of open source examples

      • Next.js Starter Kit

        Kickstart your Next.js collaborative app

      • DevTools

        Browser extension for debugging

      • Tutorial

        Step-by-step interactive tutorial

      • Guides

        How-to guides and tutorial

    • Company
      • Blog

        The latest from Liveblocks

      • Customers

        The teams Liveblocks empowers

      • Changelog

        Weekly product updates

      • Security

        Our approach to security

      • About

        The story and team behind Liveblocks

  • Docs
  • Pricing
  • Ready-made features
    • AI Copilots
    • Comments
    • Multiplayer Editing
    • Notifications
    • Presence
    Platform
    • Monitoring Dashboard
    • Realtime Infrastructure
    Solutions
    • People platforms
    • Sales tools
    • Startups
    Use cases
    • Multiplayer forms
    • Multiplayer text editor
    • Multiplayer creative tools
    • Multiplayer whiteboard
    • Comments
    • Sharing and permissions
    • Document browsing
  • Resources
    • Documentation
    • Examples
    • React components
    • DevTools
    • Next.js Starter Kit
    • Tutorial
    • Guides
    • Release notes
    Technologies
    • Next.js
    • React
    • JavaScript
    • Redux
    • Zustand
    • Yjs
    • Tiptap
    • BlockNote
    • Slate
    • Lexical
    • Quill
    • Monaco
    • CodeMirror
  • Company
    • Pricing
    • Blog
    • Customers
    • Changelog
    • About
    • Contact us
    • Careers
    • Terms of service
    • Privacy policy
    • DPA
    • Security
    • Trust center
    • Subprocessors
  • HomepageSystem status
    • Github
    • Discord
    • X
    • LinkedIn
    • YouTube
    © 2025 Liveblocks Inc.
Blog/Engineering

We’ve open-sourced our customizable React emoji picker

Introducing Frimousse, a headless open-source emoji picker component for React.

, , on March 20th
We’ve open-sourced our customizable React emoji picker
March 20th·3 min read
Share article

We’ve just released Frimousse, a new open-source emoji picker for React. Unstyled, designed to be lightweight and highly composable, the new component can seamlessly fit into any application.

Origin

We first felt the need for a new emoji picker when building Liveblocks Comments, which is where we built our first version.

The Liveblocks Comments emoji picker.

We built this because we discovered that there were no existing components that fit our specific needs:

  • It needed to be fully unstyled, so we could apply our styling from our existing components. For example, we use a number of complex CSS variables for sizing, colours, and more, and we needed the emoji picker to inherit these.
  • We wanted a small bundle, only requiring users to download emoji lists when the picker is used, caching data so re-downloads aren’t required.
  • We wanted it to always have the latest emojis, as other libraries often require you to install new versions to get updates.

Frimousse

We’d always loved the thought of open-sourcing our Comments emoji picker, and after two years of production use, we decided it was time to give back to the web community—try a demo below.

A live example of the emoji picker.

Loading…
Category

Primitives

Frimousse uses primitive components, similar to Radix UI, that essentially allow you to create an emoji picker out of building blocks.

import { EmojiPicker } from "frimousse";
export function MyEmojiPicker() { return ( <EmojiPicker.Root> <EmojiPicker.Search /> <EmojiPicker.Viewport> <EmojiPicker.Loading>Loading…</EmojiPicker.Loading> <EmojiPicker.Empty>No emoji found.</EmojiPicker.Empty> <EmojiPicker.List /> </EmojiPicker.Viewport> </EmojiPicker.Root> );}

Because each component is headless, you can apply your own styles, whilst Frimousse handles the functionality. For example, it’s compatible with Tailwind CSS, CSS-in-JS, and vanilla CSS. We also have a pre-built shadcn/ui component, with ready-made styles.

Comments primitives

If you’re using our Comments primitives, it’s now easy to add your own emoji picker. Check out our Tailwind CSS primitives example to learn how to set it up.

Get started

To build your custom emoji picker, visit our new mini-site for documentation and examples.

Get Frimousse

Comments primitives

If you’re already using our Comments primitives, it’s now easy to add your own emoji picker with Frimousse.

Our Comments primitives example.

You can find the source code in our examples gallery.

Contributors

Contributors include:marcbouchenoire

1 authors

Product UpdatesComments

Ready to get started?

Join thousands of companies using Liveblocks ready‑made collaborative features to drive growth in their products.

Book a demo

Related blog posts

  • Why we built our AI agents on WebSockets instead of HTTP

    Why we built our AI agents on WebSockets instead of HTTP

    Picture of Jonathan Rowny
    Picture of Nimesh Nayaju
    September 29th
    Engineering
  • What's the best vector database for building AI products?

    What's the best vector database for building AI products?

    Picture of Jonathan Rowny
    September 15th
    Engineering
  • Configure each user’s notification settings for email, Slack, and more

    Configure each user’s notification settings for email, Slack, and more

    Picture of Chris Nicholas
    March 6th
    Product & Design