VCF to LDIF — Import vCard Contacts into Thunderbird
Turn a .vcf / vCard file into the LDIF Thunderbird's Address Book import still understands — names, phones, emails and addresses mapped, UTF-8 names base64-encoded. The file is parsed on your device with JavaScript. There is no upload endpoint.
Drop your .vcf / vCard file here
One file, up to 10 MB — converted to Thunderbird LDIF on your device. Nothing is uploaded.
Why Thunderbird wants LDIF (or CSV), not always a vCard
Thunderbird's Address Book grew up as an LDAP client. The file it has historically imported — and still writes on export — is LDIF, the LDAP Data Interchange Format (RFC 2849). Each contact is one record: a dn: line, objectclass: lines, then inetOrgPerson attributes (cn, givenName, sn, mail, telephoneNumber, …) plus Thunderbird's mozilla* extras for a second email and URLs. CSV is the other format the importer has always accepted. A .vcf was not on that list for a long time.
That picture changed. Newer Thunderbird (102 and later) can import a vCard directly: open the Address Book, choose Import, pick a .vcf. If you are on a current release and that path already maps names, phones and emails, you do not need this page. Use this converter for older builds that still expect LDIF or CSV, for files where the native vCard import drops a second email or an accented name, and for other LDAP-style tools (ldapadd, a directory server, a migration script) that read the same attribute names.
Conversion is local. parseVcf turns each BEGIN:VCARD block into a contact; contactsToLdif writes one Thunderbird-style record. No server step. The fixture — accented cn:: base64, a folded continuation line, a round trip through parseLdif — is in scripts/test-ldifwrite.mjs.
Which vCard fields become which LDIF attributes
Each mapped property becomes one attribute on a mozillaAbPersonAlpha record. Unmapped properties are dropped, not copied into a note. The table is VCF_TO_LDIF_TABLE in lib/ldifWrite.js — the same list the writer walks.
| vCard 3.0 property | Contact field | LDIF attribute |
|---|---|---|
| FN | Full name | cn |
| N (given) | First name | givenName |
| N (family) | Last name | sn |
| EMAIL (first) | Email 1 | mail |
| EMAIL (second) | Email 2 | mozillaSecondEmail |
| TEL;TYPE=WORK (or first untyped TEL) | Phone (work) | telephoneNumber |
| TEL;TYPE=CELL | Phone (cell) | mobile |
| TEL;TYPE=HOME | Phone (home) | homePhone |
| TEL;TYPE=FAX | Phone (fax) | facsimileTelephoneNumber |
| ORG | Company | o |
| TITLE | Job title | title |
| ADR (street) | Street | street |
| ADR (locality) | City | l |
| ADR (region) | State | st |
| ADR (postal) | ZIP | postalCode |
| ADR (country) | Country | c |
| URL | Website | mozillaHomeUrl |
| NOTE | Notes | description |
The distinguished name is dn: cn=<cn>,mail=<mail>, omitting ,mail= when there is no email. cn is FN, or givenName plus sn when FN is missing. mail is the first EMAIL; mozillaSecondEmail is the second. A third email is not written. telephoneNumber is the first TEL;TYPE=WORK, or the first phone parseVcf labels other (untyped TEL, and TYPE=FAX). mobile and homePhone take CELL and HOME — one of each. facsimileTelephoneNumber is in the writer table but is not filled from a typical TEL;TYPE=FAX line.
One address: the ADR parseVcf kept is written as street, l, st, postalCode, c. URL becomes mozillaHomeUrl, not mozillaWorkUrl. Empty attributes are omitted. Every record still gets the five objectclass lines Thunderbird writes on export: top, person, organizationalPerson, inetOrgPerson, mozillaAbPersonAlpha.
Base64 values and 76-character folding (RFC 2849)
LDIF cannot put raw UTF-8 on an attribute: value line when the value is not safe ASCII. RFC 2849 requires a double colon and a base64 payload — cn:: TWFyw61hIEdhcmPDrWE= is María García — whenever the value contains a non-ASCII character, starts with a space, a colon or <, or contains a CR or LF. The writer encodes UTF-8 bytes (not Latin-1) as attr:: plus base64. Nothing else is escaped: a comma in Acme, Inc., an apostrophe in O'Brien, a plus in a phone number all stay literal.
Lines longer than 76 characters are folded: leftover text continues on the next physical line, which starts with a single space. Folding happens after base64. Line endings are LF, matching Thunderbird's export (vCard uses CRLF). The distinguished name is the exception to base64: Thunderbird writes dn: cn=María García,mail=… as UTF-8, and this writer does the same so the reverse parser still keys records on a plain dn: line.
scripts/test-ldifwrite.mjs checks both sides: an accented cn:: payload that decodes back to María García, a note long enough to force a continuation line, and parseLdif(contactsToLdif(contacts)) returning the same names, emails and phones. Empty input yields count 0.
What is not carried over
This is a field mapper, not a vCard clone. These never reach the .ldif:
- Photos. No
PHOTOis read, so nothing is written asjpegPhoto. - Custom
X-fields (X-ABLabel,X-SOCIALPROFILE, and anything elseparseVcfdoes not already put on the contact). - A second address. The parser keeps one
ADR; the writer emits it asstreet/l/st/postalCode/c. mozillaHome* address attributes are not written. - A third email; extra phones beyond one work, one cell and one home;
TEL;TYPE=FAXasfacsimileTelephoneNumber(parseVcflabels itother);NICKNAME,BDAY, categories.
vCards with no name, email or phone — an empty BEGIN:VCARD block — are skipped and counted on the result line.
Importing the .ldif in Thunderbird
As of 2026, the path that still works on the older Tools-menu Address Book is: open Thunderbird → Address Book → Tools → Import → Address Book → LDIF, then pick the downloaded file. Thunderbird 102 and later put Import on the Address Book tab itself (a button, or the ⋯ menu on a book); the file-type list still includes LDIF. Menu labels move between releases — if Tools → Import is missing, look on the Address Book tab. After import, check an accented name and a second email; those two fields show whether the file was read as UTF-8 LDIF.
If LDIF import fails, convert the same .vcf on the VCF to CSV converter and map columns by hand. On a current Thunderbird the original .vcf may import directly — this LDIF step is the fallback. One file, up to 10 MB.
Going the other way
Already have a Thunderbird LDIF and need a vCard for a phone or Google Contacts? Use the LDIF to VCF converter. Same attributes, the other direction: base64 decoded, folded lines joined, mailing lists skipped. A round trip of names, emails and typed phones is what scripts/test-ldifwrite.mjs asserts against parseLdif.
VCF to LDIF — FAQ
Does Thunderbird still need LDIF, or can it import a vCard directly?
Newer Thunderbird (102 and later) can import a .vcf from the Address Book. This converter is for older builds whose importer still expects LDIF or CSV, and for other LDAP-style tools that read inetOrgPerson records. If a current Thunderbird already imports your vCard cleanly, you do not need the extra step.
Is my .vcf uploaded anywhere?
No. The writer is JavaScript that runs in this tab — there is no upload endpoint. After the page has loaded you can disconnect from the internet and still drop a .vcf, preview the first LDIF records, and download a .ldif. Nothing in lib/ldifWrite.js, lib/vcard.js or the converter component makes a network request with your file.
Why do some lines say cn:: instead of cn:?
A double colon is how LDIF (RFC 2849) marks a base64 value. The writer uses it whenever a value is not plain ASCII — accented names, umlauts, CJK — or when it starts with a space, a colon or <, or contains a CR or LF. cn:: TWFyw61hIEdhcmPDrWE= is María García. The bytes are UTF-8, then base64, matching what Thunderbird writes on export.
Which vCard fields become which LDIF attributes?
FN becomes cn; N given/family become givenName and sn; the first two EMAIL lines become mail and mozillaSecondEmail; TEL types map to telephoneNumber (work, or the first phone parseVcf labels other — including TYPE=FAX), mobile (cell) and homePhone (home); facsimileTelephoneNumber is in the writer table but parseVcf does not assign type fax from TYPE=FAX; ORG/TITLE to o/title; the one ADR to street, l, st, postalCode and c; URL to mozillaHomeUrl; NOTE to description. The table on this page is generated from that list in lib/ldifWrite.js.
What is not carried over into the .ldif?
Photos (no PHOTO / jpegPhoto), custom X- fields (X-ABLabel, X-SOCIALPROFILE and the rest), a second address, a third email, extra phones beyond one work/cell/home, TEL;TYPE=FAX as facsimileTelephoneNumber (parseVcf labels it other), NICKNAME, BDAY and categories. vCards with no name, email or phone are skipped and counted on the result line.
How do I import the .ldif into Thunderbird?
As of 2026, on the older Tools-menu Address Book the path is Address Book → Tools → Import → Address Book → LDIF, then pick the downloaded file. Thunderbird 102 and later put Import on the Address Book tab itself (a button or the ⋯ menu); the file-type list still includes LDIF. Menu labels move between releases — if Tools → Import is missing, look on the Address Book tab. After import, check an accented name and a second email.
Can I convert the other way, from LDIF back to vCard?
Yes. The LDIF to VCF converter on this site is the reverse mapping: the same attributes, base64 decoded, folded lines joined, mailing lists skipped. A round trip of names, emails and typed phones is what scripts/test-ldifwrite.mjs asserts against lib/ldif.js.
The fixture in scripts/test-ldifwrite.mjs checks an accented cn::, a folded note, mozillaSecondEmail and a parseLdif round trip. Last checked: August 26, 2026. About this site