Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Emoji Toolkit Laravel Package

joypixels/emoji-toolkit

JoyPixels Emoji Toolkit is a PHP library for working with emoji in web and PHP projects: convert shortnames to Unicode or images, parse emoji in text, and render JoyPixels assets consistently.

Deep Wiki
Context7

Getting Started

composer require joypixels/emoji-toolkit

This is not a Laravel package — there is no service provider, no facade, no publishable config. It is a plain PHP library (JoyPixels\Client, historically Emojione\Client in older trees). Expect to wire everything yourself.

Where to look first:

  1. Open vendor/joypixels/emoji-toolkit/ and read the Client class. Every option is a public property, and the conversion methods are the API surface:
    • toImage($str) — unicode/shortname → <img> tags
    • toShort($str) — unicode → :shortname:
    • shortnameToUnicode($str), unicodeToShortname($str)
    • shortnameToImage($str), unicodeToImage($str)
  2. Find the bundled asset directory (PNG/SVG emoji images). These are not served automatically — you must copy or symlink them into public/.
  3. Check the LICENSE file before writing any code. The repo reports NOASSERTION; JoyPixels ships under its own free-use license with attribution requirements and commercial restrictions.

Minimal setup — publish the assets:

# adjust the source path to whatever the package ships
cp -r vendor/joypixels/emoji-toolkit/assets/emoji public/emoji

Register a singleton so you configure it once (app/Providers/AppServiceProvider.php):

use JoyPixels\Client;

$this->app->singleton(Client::class, function () {
    $client = new Client();
    $client->imageType    = 'svg';      // 'png' or 'svg'
    $client->imagePathSVG = '/emoji/'; // URL prefix, not a filesystem path
    $client->unicodeAlt   = true;      // keep the unicode char in alt=""
    $client->ascii        = false;     // don't emit :) style fallbacks
    return $client;
});

(Property names have shifted across major versions — verify against the Client class you actually installed.)

First use case: rendering user-generated content (comments, chat, bios) as a consistent emoji set instead of relying on the visitor's OS:

$html = app(Client::class)->toImage(e($comment->body));

Implementation Patterns

Store shortnames, render images. The most robust pattern for anything that gets searched, indexed, or exported: normalize emoji to :shortname: on write, convert back on read. Unicode emoji are multi-codepoint, break LIKE queries, and change appearance per platform.

// saving
$model->body_short = $client->toShort($request->input('body'));

// rendering
echo $client->shortnameToImage(e($model->body_short));

Blade directive + helper. Wrap the singleton so views stay readable:

Blade::directive('emoji', fn ($expr) => "<?php echo app(\JoyPixels\Client::class)->toImage($expr); ?>");
<div class="prose">@emoji($comment->body_short)</div>

Sanitize first, convert second. toImage() emits <img> tags — running HTMLPurifier (or strip_tags) afterward will strip them, and running it before is required so you never introduce attributes Purifier didn't vet. Keep conversion as the last step before output.

Attribute accessors / casts. Centralize conversion on the model so controllers and API resources don't each reach for the client:

public function getBodyHtmlAttribute(): string
{
    return app(Client::class)->shortnameToImage(e($this->body_short));
}

API responses. Return emoji as shortnames (:rocket:) in JSON. It's stable, diffable in tests, and keeps payloads small. Let the client render — or ship the JS toolkit on the frontend and keep its imagePath config identical to the PHP one.

Mail and notifications. Rendered image URLs must be absolute and web-reachable from an email client. Set imagePathSVG to config('app.url').'/emoji/' in the mail context (a separate client binding, or override per-call), otherwise recipients get broken images.

Cache rendered output. Conversion is regex-heavy and runs per request. Cache the final HTML per comment/article (Cache::remember("comment.html.{$id}", ...)) and bust it when the emoji toolkit version or config changes.

Keep the frontend/backend sets in sync. If you use the JS toolkit in the browser and the PHP port on the server, pin both to the same version — otherwise the same shortname renders as different artwork in a live preview vs. after save.

Gotchas and Tips

  • Licensing is the real blocker. NOASSERTION means you must actually read the license. JoyPixels' free tier requires visible attribution and restricts redistribution and some commercial uses; a paid license is needed for many production scenarios. Get this signed off before it becomes load-bearing.
  • Asset weight. The full SVG/PNG sets are thousands of files and tens of megabytes. Prefer SVG, or use a sprite sheet ($client->sprites = true with the sprite CSS) rather than dumping 3,000+ files into public/. Consider serving from a CDN and pointing imagePath* at it.
  • imagePathSVG / imagePathPNG are URL prefixes, not filesystem paths. Setting them to storage_path(...) produces silently broken images. Files must be reachable over HTTP.
  • Conversion is not idempotent. Calling toImage() twice on already-converted HTML mangles the output (it will try to match inside alt attributes). Convert exactly once, at the edge.
  • Order of operations matters: escape/sanitize → shortname-to-unicode or unicode-to-image → echo. Never htmlspecialchars() after toImage().
  • MySQL charset. If you store unicode emoji anyway, the column must be utf8mb4 (not utf8) and the connection charset too — otherwise you get Incorrect string value or silent ? truncation. Watch index length on utf8mb4 columns in older MySQL.
  • ZWJ sequences and skin tones. Multi-codepoint emoji (families, professions, 👨‍👩‍👧‍👦) are the usual failure mode with older releases. Test a few before trusting the version you installed, and check unifyUnicode / unifyHTML behavior if you're normalizing input.
  • ASCII conversion is lossy and one-way. ascii = true turns :) into an emoji — fine for display, never for round-tripping stored content.
  • Pin the exact version. Emoji set releases change shortnames and artwork. composer require joypixels/emoji-toolkit:1.x.y rather than ^1.0, and assert on shortnames in tests, not on <img src="..."> markup, which churns every release.
  • No queue/streaming awareness. Very long text (chat logs, full-page exports) can be slow. Chunk or pre-render; don't call it in a loop over 500 rows without caching.
  • Extension points are thin: subclass JoyPixels\Client if you need custom paths per context (web vs. email), and keep your own config file (config/emoji.php) as the single source of truth for size, type, and asset host — the package itself won't give you one.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels