//go:embed para Archivos y Plantillas
//go:embed le indica al compilador que copie archivos en tu paquete para que se incluyan dentro del binario.
Busca en todas las páginas de la documentación
//go:embed le indica al compilador que copie archivos en tu paquete para que se incluyan dentro del binario.
Puedes leerlos a través de string, []byte, o embed.FS sin abrir rutas en el host de despliegue.
go:embed se introdujo en Go 1.16 y reemplazó la mayoría de los generadores de código estilo bindata para activos estáticos.
La directiva se aplica a variables en el mismo paquete, usando patrones glob relativos al archivo fuente.
embed.FS implementa io/fs.FS, por lo que http.FileServer, fs.WalkDir y template.ParseFS se componen de forma natural.
Los datos incrustados son de solo lectura; muta copias en memoria si necesitas cambiar el contenido en tiempo de ejecución.
Tarjeta de receta de referencia rápida - lista para copiar y pegar.
package assets
import "embed"
//go:embed migrations/*.sql
var Migrations embed.FS
//go:embed config/default.yaml
var DefaultConfig []byteCuándo usar esto:
example.com/app/
main.go
assets/
migrations/
001_init.sql
templates/
home.html
// main.go
package main
import (
"embed"
"html/template"
"io/fs"
"log"
"net/http"
)
//go:embed assets/migrations/*.sql
var migrations embed.FS
//go:embed assets/templates/*.html
var templates embed.FS
func main() {
sql, err := fs.ReadFile(migrations, "assets/migrations/001_init.sql")
if err != nil {
log.Fatal(err)
}
log.Printf("bytes de migración: %d", len(sql))
tpl, err := template.ParseFS(templates, "assets/templates/*.html")
if err != nil {
log.Fatal(err)
}
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
_ = tpl.ExecuteTemplate(w, "home.html", nil)
})
log.Fatal(http.ListenAndServe(":8080", nil))
}Lo que esto demuestra:
//go:embed en un mismo paquete.assets/migrations/...).template.ParseFS carga plantillas sin rutas de disco en tiempo de ejecución.//go:embed sobre las variables a nivel de paquete.embed.FS sirve esos bytes a través de las APIs de io/fs.init lee el sistema de archivos en la máquina de destino.| Regla | Detalle |
|---|---|
| Tipos de variables | Solo string, []byte, embed.FS |
| Ubicación | Mismo directorio del paquete o subdirectorio |
| Prohibido | .., rutas absolutas, enlaces simbólicos fuera del árbol |
| Archivos ocultos | Los nombres que comienzan con . se excluyen a menos que se nombren explícitamente |
| Coincidencia vacía | Error de compilación si un patrón no coincide con nada |
//go:embed static/*
var static embed.FS
sub, _ := fs.Sub(static, "static")
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.FS(sub))))fs.Sub elimina el prefijo incrustado para que las URLs se mapeen limpiamente.
import _ "embed" // requerido cuando se usa //go:embed sin referenciar embed en el códigoSi solo incrustas en []byte y nunca nombras embed.FS, la importación vacía satisface al compilador.
ReadFile usa la ruta incrustada completa, incluyendo los directorios del patrón. Solución: registra fs.WalkDir una vez o coincide exactamente con el prefijo del patrón.os.Chdir en pruebas porque los datos no se leen del disco en tiempo de ejecución. Solución: prueba a través de las APIs de FS incrustadas.ExecuteTemplate usa el nombre definido de la plantilla, no siempre el nombre del archivo. Solución: llama a tpl.DefinedTemplates() durante el desarrollo.| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
| Archivos de disco + ConfigMap/volumen | Activos grandes o actualizados frecuentemente | Necesitas portabilidad estricta de binario único |
Herramientas go:generate bindata | Proyectos heredados que ya usan generadores | Iniciando código nuevo en Go 1.16+ |
| Incrustar solo valores predeterminados; obtener el resto | Híbrido en línea/fuera de línea | Cada byte debe estar aislado |
text/template con ParseFiles en desarrollo | Iteración rápida de plantillas localmente | La producción no debe depender de rutas de plantillas |
Sí, si coinciden con las reglas de patrones.
Raro para producción; útil para diagnósticos o herramientas estilo go version -m.
Embed lee de la disposición del árbol fuente en tiempo de compilación.
Los dependencias vendored son módulos separados; incrusta tus propios archivos de paquete.
Sí.
Los patrones siguen las reglas de path.Match; prueba con un directorio pequeño primero.
Elige el tipo de variable.
string evita copias cuando solo lees; []byte ayuda cuando mutas una copia.
Sí, con significado limitado.
ModTime refleja los metadatos de incrustación, no la marca de tiempo original del archivo en disco en tiempo de ejecución.
Cada paquete necesita su propia directiva //go:embed.
La duplicación aumenta el tamaño del binario si ambos paquetes se enlazan en el mismo binario.
Herramientas como goose y golang-migrate aceptan io/fs.FS.
Pasa embed.FS o fs.Sub de tu directorio de migraciones.
No automáticamente.
El enlazador almacena los bytes que proporcionas; comprime los activos tú mismo si el tamaño importa.
go:embed es compatible con muchos objetivos, pero verifica tu toolchain específico.
TinyGo tiene restricciones de tamaño; mantén los activos incrustados pequeños.
Sí.
Coloca diferentes variables //go:embed en archivos con líneas //go:build opuestas.
Versiones de la Pila: Esta página fue escrita para Go 1.26.x (GC por defecto Green Tea, go fix modernizers - verifica el parche en la compilación), chi (última - verifica en la compilación), gin (última - verifica en la compilación), echo (última - verifica en la compilación), google.golang.org/grpc (última - verifica en la compilación), sigs.k8s.io/controller-runtime (última - verifica en la compilación), kubebuilder (última - verifica en la compilación), tinygo (última - verifica objetivos de placa en la compilación), wazero (última - verifica en la compilación) y golangci-lint (última - verifica el conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 16 jul 2026