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·Pesquisadores de cultura de emoji + redatores de guias por plataforma·20 de junho de 2026

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
| Emoji | Ponto de código | Bytes UTF-8 | Unidades de código UTF-16 |
|---|---|---|---|
| 😂 | U+1F602 | 4 | 2 |
| ❤️ | U+2764 U+FE0F | 6 | 4 |
| 👨👩👧 | U+1F468 U+200D U+1F469 U+200D U+1F467 | 17 | 10 |
| 🇺🇸 | U+1F1FA U+1F1F8 | 8 | 4 |
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·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
