Forgemoji

O que todo criador de conteúdo precisa saber sobre a codificação de emoji

Emoji é texto, não imagem. Eles têm pontos de código, pares substitutos, sequências ZWJ e seletores de variação. A maioria dos criadores de conteúdo os trata como glifos opacos. A codificação importa, e os bugs são reais.

Lois Chen

Lois Chen·Pesquisadores de cultura de emoji + redatores de guias por plataforma·20 de junho de 2026

Hand-drawn infographic: emoji encoding and cross-platform rendering

A maioria dos criadores de conteúdo trata emoji como imagens opacas. Você clica no seletor, acha a cara certa, envia, e o dispositivo do destinatário renderiza do jeito que ele renderiza. Isso funciona em 95% dos casos. Os outros 5% (a mojibake, os clusters quebrados, os pontos de interrogação no lugar de emoji, as renderizações específicas de plataforma) acontecem porque emoji é texto, e a codificação importa.

Emoji é texto, não imagem

O fato mais importante sobre emoji é que ele é texto, não imagem. Cada emoji tem um ponto de código Unicode (codepoint, um número atribuído pelo Unicode Consortium), e o ponto de código é armazenado como parte do fluxo de texto. Quando você envia uma mensagem com 😂, a mensagem contém o ponto de código U+1F602, que o dispositivo do destinatário então renderiza usando o glifo próprio dele.

O mesmo ponto de código renderiza diferente em plataformas diferentes, porque cada plataforma desenha o próprio glifo. 😂 é uma cara amarela chapada no iOS, uma mancha no Google, uma renderização 3D na Samsung e um monocromático de alto contraste no proxy de imagem do Twitter. O ponto de código é o mesmo; o desenho é específico da plataforma. Esse é o mesmo modelo do alfabeto latino: o ponto de código de "A" é U+0041, e o jeito como o "A" aparece depende da fonte.

O básico: pontos de código e UTF-8

Todo caractere Unicode tem um ponto de código, escrito em hexadecimal com o prefixo U+. Os pontos de código de emoji ficam no Plano Multilíngue Suplementar (Supplementary Multilingual Plane, SMP), ou seja, acima de U+FFFF. É aqui que a codificação fica interessante.

Em UTF-8 (a codificação dominante na web), cada ponto de código é codificado em 1 a 4 bytes. Emoji são sempre 4 bytes. Em UTF-16 (a codificação usada por strings do JavaScript e pelo Windows), pontos de código acima de U+FFFF são codificados como pares substitutos (surrogate pair), duas unidades de código de 16 bits que, juntas, representam um único ponto de código. É por isso que emoji tem 2 caracteres de comprimento no JavaScript, não 1. "😂".length === 2 em JavaScript. Isso pega no contrapé de muito código de front-end que faz contagem de caracteres.

Pontos de código de emoji comuns

EmojiPonto de códigoBytes UTF-8Unidades de código UTF-16
😂U+1F60242
❤️U+2764 U+FE0F64
👨‍👩‍👧U+1F468 U+200D U+1F469 U+200D U+1F4671710
🇺🇸U+1F1FA U+1F1F884

A última linha é interessante. 🇺🇸 (bandeira dos Estados Unidos) são dois pontos de código de indicador regional (U+1F1FA para "U" e U+1F1F8 para "S") que se combinam para formar o glifo da bandeira. Não existem pontos de código para as bandeiras em si, elas são calculadas a partir do par. É por isso que dá para digitar "US" e obter 🇺🇸 em uma plataforma que dá suporte a indicadores regionais, mas os dados por baixo são dois pontos de código, não um.

Por que alguns emoji são vários pontos de código

Alguns emoji são pontos de código únicos (😂 é só U+1F602). Alguns são sequências. 👨‍👩‍👧 (família: homem, mulher, menina) são cinco pontos de código unidos por juntores de largura zero (U+200D): U+1F468 (homem) + U+200D (ZWJ) + U+1F469 (mulher) + U+200D (ZWJ) + U+1F467 (menina). O ZWJ é uma instrução ao renderizador: una os pontos de código dos meus dois lados em um único glifo.

Esse é um mecanismo poderoso. Um usuário consegue construir uma família de qualquer composição (👨‍👩‍👧‍👦 (dois adultos, duas crianças) ou 👨‍👨‍👧 (dois pais, uma filha)) digitando os pontos de código em sequência, mesmo que nenhuma plataforma tenha renderizado aquela combinação exata antes. O resultado depende de a plataforma de renderização conhecer a sequência ZWJ. A maioria das plataformas modernas conhece, mas a renderização pode variar, e plataformas mais antigas podem mostrar o emoji como glifos separados.

Pares substitutos e JavaScript

A questão dos pares substitutos é a fonte de muitos bugs de emoji em JavaScript. Strings em JavaScript são UTF-16, e pontos de código acima de U+FFFF são armazenados como duas unidades de código de 16 bits (um substituto alto e um substituto baixo). Isso significa que "😂".length === 2, não 1, porque a string contém duas unidades de código UTF-16.

O bug mais comum é a contagem de caracteres. Um message.length ingênuo devolve a contagem de unidades de código UTF-16, não a contagem de caracteres percebidos pelo usuário. Uma mensagem com 5 emoji e 10 caracteres ASCII vai reportar comprimento 20, não 15. A correção é usar o operador spread ([...message].length) ou a API Intl.Segmenter, que contam por ponto de código ou por cluster de grafemas (grapheme cluster).

Seletores de variação

Seletores de variação são pontos de código que mudam a renderização do ponto de código anterior. O mais comum é U+FE0F (VARIATION SELECTOR-16, VS-16), que força o estilo de emoji em um caractere que também tem um estilo de texto.

O exemplo mais claro é o coração. ❤ (U+2764) renderiza por padrão como um glifo de coração em estilo de texto (um coração vermelho escuro e pesado, parecendo um ornato de impressora. ❤️ (U+2764 U+FE0F) é o mesmo ponto de código de coração seguido de VS-16, que força o estilo de emoji) um glifo de coração vermelho vivo e brilhante. Os dois renderizam de jeito bem diferente, e a diferença é um único ponto de código.

É por isso que digitar "heart" no seu seletor de emoji produz um resultado diferente de digitar o nome Unicode e torcer pelo melhor. O seletor sempre adiciona o seletor de variação automaticamente. O ponto de código puro, digitado à mão, não.

Modificadores de tom de pele

Os modificadores de emoji da escala Fitzpatrick (U+1F3FB a U+1F3FF) mudam o tom de pele de um emoji que aceita isso. 🏋️ (halterofilista) é a combinação U+1F3CB (halterofilista) + U+FE0F (VS-16) + U+1F3FB (tom de pele claro). Sem o modificador, é usado o emoji amarelo padrão. Com o modificador, é renderizado um tom de pele específico.

O importante é saber que modificadores de tom de pele só funcionam em emoji projetados explicitamente para aceitá-los. Adicionar um modificador de tom de pele a um emoji que não dá suporte não faz nada (o modificador é ignorado), e algumas plataformas tratam combinações sem suporte de forma inconsistente. O gerador da Forgemoji segue a especificação do Unicode, combinações com suporte recebem um tom de pele, combinações sem suporte recebem o amarelo padrão.

Bugs comuns e como evitá-los

  • Mojibake em bancos de dados. Armazenar emoji em um banco que espera ISO-8859-1 ou outra codificação pré-Unicode vai corromper os dados. Use UTF-8 em toda a pilha.
  • Cálculos de comprimento. Uma contagem ingênua de caracteres subestima o comprimento percebido pelo usuário em conteúdo denso em emoji. Use clusters de grafemas.
  • Indexação em mecanismos de busca. Se o seu buscador tokeniza por espaço em branco, o emoji vai ser indexado como parte do texto ao redor. A maioria dos mecanismos modernos (Elasticsearch, OpenSearch, Algolia) trata emoji corretamente com os tokenizers adequados.
  • Acessibilidade. Leitores de tela anunciam o nome curto do CLDR. Para emoji customizado ou gerado por IA, esse nome curto pode estar errado ou ausente. Teste com leitores de tela.
  • Limites de armazenamento no banco. VARCHAR(255) conta unidades de código, não caracteres. Uma coluna VARCHAR(255) no MySQL com utf8mb4 armazena 255 caracteres, mas o limite de bytes é 4 por caractere, então o orçamento real de armazenamento para conteúdo denso em emoji é 1020 bytes. Planeje de acordo.

Conclusões práticas

  • Use UTF-8 em toda a pilha. Em 2026 não existe motivo para usar uma codificação pré-Unicode.
  • Para código sensível a comprimento (colunas no banco, contadores de caracteres), use clusters de grafemas ou pontos de código, não unidades de código UTF-16.
  • Teste a renderização de emoji nas plataformas que importam para os seus usuários. iOS, Android e Windows renderizam de jeito diferente.
  • Para sequências ZWJ, teste em dispositivos mais antigos. A renderização era inconsistente em 2018 e ainda não está totalmente consistente em 2026.
  • Seletores de variação importam. Se você quer o estilo de emoji, adicione VS-16. Se não quer, não adicione.

A Forgemoji gera um PNG transparente limpo. A codificação é problema seu, não nosso, mas temos um deep-dive sobre sequências ZWJ nas notas de engenharia.

Veja como funciona →

Fontes

Leituras recomendadas

  • Como o emoji virou uma linguagem: dos símbolos Unicode à taquigrafia cultural — por que pontos de código e nomes importam
  • Guia de acessibilidade de emoji: como tornar emoji customizado legível para todo mundo — colocando a codificação em prática
  • Como construímos um gerador de emoji com IA com exportação em PNG, GIF e WebP transparente — por que os formatos de exportação variam

Fontes

Source: Especificação principal do Unicode 16.0 , caracteres suplementares e emoji Unicode Consortium (verificado em junho de 2026)

Source: MDN , Tamanho de string e pares substitutos Mozilla Developer Network (verificado em junho de 2026)

Lois Chen

Lois Chen·Editor de conteúdo

Revisado em 20 de junho de 2026

Como escrevemos isto: Os posts são escritos a partir de testes de plataforma em primeira mão (servidores de Discord, grupos do Telegram, TikTok), entrevistas com power users no r/discordapp e na comunidade de stickers do Telegram, e checagens semanais das release notes do Unicode. Todo guia é revisado por pelo menos um editor para garantir precisão técnica e atualizado quando a plataforma em questão muda suas regras. Os dados de uso de emojis vêm do Google Trends público, dos relatórios UDF (frequência de emojis Unicode) e dos nossos próprios logs de geração do Forgemoji.

Fontes: Equipe editorial interna do Forgemoji — consulte a página Sobre nós para notas individuais dos colaboradores