A framework-agnostic Go module for generating vCard files (.vcf) compatible with major contact managers (iOS, Android, Gmail, iCloud, etc.). Inspired by php-vcard, this package works seamlessly with any Go web framework including Gin, Echo, Fiber, Chi, and standard net/http.
β’ Framework-agnostic: Use with Gin, Echo, Fiber, Chi, or standard net/http β’ vCard 3.0/4.0 support: Generate standards-compliant vCard files β’ Rich content: Supports names, emails, phones, addresses, organizations, photos, and more β’ Modern Go: Type-safe, extensible, and robust (Go 1.22+) β’ High test coverage: 90+% coverage with comprehensive test suite and CI/CD integration β’ Easy integration: Simple API, drop-in for handlers/middleware β’ Production ready: Used in production environments β’ Multiple formats: File output and HTTP response generation β’ Framework examples: Ready-to-use examples for popular Go web frameworks
β’ π Installation β’ π Usage Examples β’ π§ Framework Adapters β’ π Documentation Wiki β’ π§ͺ Testing & Development β’ π€ Contributing β’ π Security Policy β’ π Support & Funding β’ π License
go get go.rumenx.com/vcard
package main
import (
"net/http"
"go.rumenx.com/vcard"
)
func vcardHandler(w http.ResponseWriter, r *http.Request) {
// Create new vCard
card := vcard.New()
// Add contact information
card.AddName("John", "Doe")
card.AddEmail("john.doe@example.com")
card.AddPhone("+1234567890")
card.AddAddress("123 Main St", "Anytown", "CA", "12345", "USA")
card.AddOrganization("Acme Corp")
// Generate vCard content
content, err := card.String()
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Send as downloadable file
w.Header().Set("Content-Type", "text/vcard")
w.Header().Set("Content-Disposition", "attachment; filename=\"john_doe.vcf\"")
w.Write([]byte(content))
}
func main() {
http.HandleFunc("/vcard", vcardHandler)
http.ListenAndServe(":8080", nil)
}
card := vcard.New()
// Set vCard version (3.0 or 4.0)
card.SetVersion(vcard.Version40)
// Add comprehensive contact details
card.AddName("Jane", "Smith").
AddMiddleName("Elizabeth").
AddPrefix("Dr.").
AddSuffix("PhD")
card.AddEmail("jane@company.com", vcard.EmailWork).
AddEmail("jane.personal@gmail.com", vcard.EmailHome)
card.AddPhone("+1-555-123-4567", vcard.PhoneWork).
AddPhone("+1-555-987-6543", vcard.PhoneHome).
AddPhone("+1-555-555-5555", vcard.PhoneMobile)
// Add detailed address
card.AddAddress(
"123 Business Ave", // Street
"Suite 100", // Extended
"Business City", // City
"CA", // Region
"90210", // Postal Code
"United States", // Country
vcard.AddressWork, // Type
)
// Add organization details
card.AddOrganization("Tech Corp Inc.").
AddTitle("Senior Software Engineer").
AddRole("Backend Developer")
// Add social/web presence
card.AddURL("https://janesmith.dev", vcard.URLWork).
AddURL("https://linkedin.com/in/janesmith", vcard.URLSocial)
// Add photo (base64 encoded or URL)
card.AddPhoto("https://example.com/photo.jpg")
// Add custom properties
card.AddCustomProperty("X-CUSTOM-FIELD", "Custom Value")
// Save to file
err := card.SaveToFile("jane_smith.vcf")
Ready-to-use examples for popular Go web frameworks are available in the examples/
directory:
Framework | Port | Example | Description |
---|---|---|---|
Gin | 8080 | gin-adapter |
Gin web framework integration |
Echo | 8081 | echo-adapter |
Echo web framework integration |
Fiber | 8082 | fiber-adapter |
Fiber web framework integration |
Chi | 8083 | chi-adapter |
Chi web framework integration |
1. Import Adapter Packages β For clean middleware integration:
go get go.rumenx.com/vcard/adapters/gin # or echo, fiber, chi
2. Copy Example Applications β For quick start with full applications:
# Clone and run complete example servers
git clone https://github.com/rumendamyanov/go-vcard.git
cd go-vcard/examples/gin-adapter && go run main.go
# Clone the repository
git clone https://github.com/rumendamyanov/go-vcard.git
cd go-vcard
# Run Gin example (port 8080)
cd examples/gin-adapter && go run main.go
# Run Echo example (port 8081)
cd examples/echo-adapter && go run main.go
# Run Fiber example (port 8082)
cd examples/fiber-adapter && go run main.go
# Run Chi example (port 8083)
cd examples/chi-adapter && go run main.go
# Download vCard file
curl "http://localhost:8080/vcard/John/Doe?email=john@example.com" -o contact.vcf
# Get JSON response
curl "http://localhost:8080/contact-json?firstName=Jane&lastName=Smith&email=jane@example.com"
Each framework adapter follows the same pattern:
package main
import (
"github.com/gin-gonic/gin"
"go.rumenx.com/vcard"
ginadapter "go.rumenx.com/vcard/adapters/gin"
)
func main() {
r := gin.Default()
r.GET("/contact/:name", ginadapter.VCard(func(c *gin.Context) *vcard.VCard {
name := c.Param("name")
card := vcard.New()
card.AddName(name, "Doe")
card.AddEmail(name + "@example.com")
return card
}))
r.Run(":8080")
}
package main
import (
"github.com/gofiber/fiber/v2"
"go.rumenx.com/vcard"
fiberadapter "go.rumenx.com/vcard/adapters/fiber"
)
func main() {
app := fiber.New()
app.Get("/contact/:name", fiberadapter.VCard(func(c *fiber.Ctx) *vcard.VCard {
name := c.Params("name")
card := vcard.New()
card.AddName(name, "Smith")
card.AddPhone("+1234567890")
return card
}))
app.Listen(":8080")
}
package main
import (
"github.com/labstack/echo/v4"
"go.rumenx.com/vcard"
echoadapter "go.rumenx.com/vcard/adapters/echo"
)
func main() {
e := echo.New()
e.GET("/contact/:name", echoadapter.VCard(func(c echo.Context) *vcard.VCard {
name := c.Param("name")
card := vcard.New()
card.AddName(name, "Johnson")
card.AddEmail(name + "@company.com")
return card
}))
e.Start(":8080")
}
package main
import (
"net/http"
"github.com/go-chi/chi/v5"
"go.rumenx.com/vcard"
chiadapter "go.rumenx.com/vcard/adapters/chi"
)
func main() {
r := chi.NewRouter()
r.Get("/contact/{name}", chiadapter.VCard(func(w http.ResponseWriter, r *http.Request) *vcard.VCard {
name := chi.URLParam(r, "name")
card := vcard.New()
card.AddName(name, "Wilson")
card.AddPhone("+1234567890")
return card
}))
http.ListenAndServe(":8080", r)
}
You can add vCard information using either individual methods or structured data:
Individual methods β Simple, type-safe, chainable:
// Recommended for most use cases
card.AddName("John", "Doe").
AddEmail("john@example.com").
AddPhone("+1234567890").
AddAddress("123 Main St", "City", "State", "12345", "Country")
Structured data β Advanced, batch operations:
// Add contact info with detailed structure
contact := vcard.Contact{
Name: vcard.Name{
First: "John",
Last: "Doe",
Middle: "William",
Prefix: "Mr.",
Suffix: "Jr.",
},
Emails: []vcard.Email{
{Address: "john@work.com", Type: vcard.EmailWork},
{Address: "john@home.com", Type: vcard.EmailHome},
},
Phones: []vcard.Phone{
{Number: "+1234567890", Type: vcard.PhoneWork},
{Number: "+1987654321", Type: vcard.PhoneMobile},
},
}
card.AddContact(contact)
For comprehensive documentation and examples:
β’ π Quick Start Guide - Get up and running quickly β’ π§ Basic Usage - Core functionality and examples β’ π Advanced Usage - Advanced features and customization β’ π Framework Integration - Integration with popular frameworks β’ π― Best Practices - Performance tips and recommendations β’ π€ Contributing Guidelines - How to contribute to this project β’ π Security Policy - Security guidelines and vulnerability reporting β’ π Funding & Support - Support and sponsorship information
# Run all tests
go test ./...
# Run tests with coverage
go test -cover ./...
# Generate HTML coverage report
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out -o coverage.html
# Run static analysis
go vet ./...
# Format code
go fmt ./...
# Run linter (if installed)
golangci-lint run
We welcome contributions! Please see our Contributing Guidelines for details on:
β’ Development setup β’ Coding standards β’ Testing requirements β’ Pull request process
If you discover a security vulnerability, please review our Security Policy for responsible disclosure guidelines.
If you find this package helpful, consider:
β’ β Starring the repository β’ π Supporting development β’ π Reporting issues β’ π€ Contributing improvements