@covve/easy-vcard

中文文档
2.1.1发布于 2026/05/13MITTypeScriptCommonJS零依赖近 30 天下载 1.2万

Simple vcard formatter

原始使用文档
文档目录18 节
  1. vCards, done thoughtfully.
  2. Table of contents
  3. Install
  4. Quick start
  5. What it handles for you
  6. Escaping — RFC 6350 §3.4
  7. Line folding — RFC 6350 §3.2
  8. VERSION:3.0 fallback
  9. API reference
  10. Name
  11. Contact
  12. Work
  13. Misc
  14. Output
  15. Not yet supported
  16. Releasing
  17. About Covve
  18. License

easy-vcard

vCards, done thoughtfully.

A small TypeScript builder for vCard 4.0 strings — fluent, RFC-correct, zero runtime dependencies. From the team at Covve.

npm version npm downloads types: TypeScript license: MIT build node


The vCard spec is small, but the details bite — escape rules, content-line folding, codepoint-safe UTF-8. easy-vcard handles them for you, so you spend your time on your product, not on RFC 6350.

  • Fluent builder. .addEmail(…).addPhone(…).toString() and you're done.
  • RFC-correct out of the box. , ; \ and newlines escape themselves. Lines fold at 75 octets. Multibyte characters (CJK, emoji, RTL) never tear.
  • Zero runtime dependencies. ~13 kB on npm. ES2020 output with .d.ts.
  • Legacy-friendly when you need it. Drop to VERSION:3.0 with one flag.
  • Battle-tested. 88 tests across escape edge cases, multi-fold lines, i18n, and the awkward corners of the spec.

Table of contents

Install

npm install @covve/easy-vcard

Requires Node.js ≥ 18 (uses the built-in structuredClone).

Quick start

import { VCard } from '@covve/easy-vcard';

const vcard = new VCard()
  .setFullName('Johnny D. Doe-Smith')
  .addFirstName('John')
  .addLastName('Doe')
  .addLastName('Smith')
  .addPrefixName('Dr.')
  .addNickname('Jonny')
  .addPhone('+1 1221112', { pref: '1', type: 'home' })
  .addEmail('[email protected]')
  .addTitle('Senior Engineer')
  .addOrganization('Jdoecomp co.', ['North Division']);

console.log(vcard.toString());
BEGIN:VCARD
VERSION:4.0
FN:Johnny D. Doe-Smith
N:Doe,Smith;John;;Dr.;
NICKNAME:Jonny
TEL;PREF=1;TYPE=home:+1 1221112
EMAIL:[email protected]
TITLE:Senior Engineer
ORG:Jdoecomp co.;North Division
END:VCARD

Each line is CRLF-terminated. Lines over 75 octets fold automatically with CRLF + space — you don't opt in.

Prefer plain objects? The Formatter accepts an IVCard directly:

import { Formatter } from '@covve/easy-vcard';

const text = new Formatter().format({
  name: { fullNames: ['Johnny D. Doe-Smith'] },
  emails: [{ value: '[email protected]' }],
});

What it handles for you

Escaping — RFC 6350 §3.4

Pass raw strings. The library escapes \, ,, ;, and newlines in property values.

new VCard()
  .setFullName('John')
  .addNotes('Hello, world; with a newline\nbreak')
  .toString();
NOTE:Hello\, world\; with a newline\nbreak

Line folding — RFC 6350 §3.2

Content lines longer than 75 UTF-8 octets are split with CRLF and a single leading space. The folder walks codepoints, not bytes — multibyte characters (中, 🍕, שלום, Müller) are never split mid-character.

VERSION:3.0 fallback

Some legacy parsers reject the 4.0 header. One flag flips it:

vcard.toString(true);                  // emits VERSION:3.0
new Formatter().format(json, true);    // same

The rest of the output still follows 4.0 conventions, so the result may not be fully valid 3.0. Use only when you must.

API reference

IParams is an object of optional parameter keys: label, language, value, pref, altId, pid, type, mediatype, calscale, sortAs, geo, timezone, encoding. Not every property accepts every parameter — see the RFC for the matrix.

Name

MethodWhat it does
setFullName(fullName)Sets the mandatory FN property. If you omit it, one is built from the N components
addFirstName(firstName)Append to N first names
addMiddleName(middleName)Append to N middle names
addLastName(lastName)Append to N last names
addPrefixName(pre)Append to N honorific prefixes
addSuffixName(suf)Append to N honorific suffixes

Contact

MethodWhat it does
addNickname(nickname, params?)Adds a NICKNAME entry
addPhoto(data, params?)Adds a PHOTO entry. data may be a URL or a base64 data URI
addAddress(street, locality, region, postCode, country, params?)Adds an ADR entry. Each component accepts string | null | undefined — null and undefined are normalized to ""
addPhone(number, params?)Adds a TEL entry
addEmail(email, params?)Adds an EMAIL entry
addUrl(url, params?)Adds a URL entry
vcard.addAddress('123 Main St.', null, undefined, 'AB-123', 'USA', { type: 'home' });
// → ADR;TYPE=home:;;123 Main St.;;;AB-123;USA

Work

MethodWhat it does
addTitle(title, params?)Adds a TITLE entry
addRole(role, params?)Adds a ROLE entry
addOrganization(organization, organizationUnits?, params?)Adds an ORG entry. organizationUnits lists sub-unit names beneath the primary name

Misc

MethodWhat it does
addNotes(notes, params?)Adds a NOTE entry
setRevision(rev, params?)Sets the REV property
setUID(uid, params?)Sets the UID property

Output

MethodReturns
toString(forceV3 = false)Formatted vCard string
toVcard(forceV3 = false)Alias for toString
toJSON()Deep clone of the internal state as a plain IVCard object — pass it to Formatter.format(…) or serialize it however you like

Not yet supported

The following vCard properties are not yet implemented. PRs welcome.

SOURCE  KIND  XML  BDAY  ANNIVERSARY  GENDER  IMPP  LANG  TZ  GEO
LOGO  MEMBER  RELATED  CATEGORIES  PRODID  SOUND  CLIENTPIDMAP
KEY  FBURL  CALADRURI  CALURI

Parsing existing vCard strings is out of scope — easy-vcard is a one-way formatter. For parsing, reach for vcard4 or vcf.

Releasing

Publishes are automated by CircleCI.

  1. Bump version in package.json and add a CHANGELOG.md entry in a PR. Merge to master.
  2. Tag the merge commit with vX.Y.Z (must match package.json) and push:
    git tag v2.3.0 && git push origin v2.3.0
    
  3. The publish job runs on tag push: install, build, lint, test, verify the tag matches package.json.version, then npm publish --access public using the NPM_TOKEN project env var.

Only strict-semver tags (vMAJOR.MINOR.PATCH) auto-publish. Pre-release tags like v2.3.0-beta.1 do not.

About Covve

Covve helps professionals turn fleeting encounters into connections that matter. We build tools that cultivate networks with care — Covve's Business Card Scanner for capturing leads, a Scanning API that powers contact intake inside other products, and a CRM that follows up so you don't have to.

easy-vcard is one of the small pieces underneath all of that — open-sourced because vCard handling is something every contact tool should get right.

Websitecovve.com
Issues & PRsgithub.com/Covve/easy-vcard

License

MIT © Covve

版本与发布记录

@covve/easy-vcard 共发布 9 个版本,首次发布于 2019/01/09;过去 12 个月发布了 1 个版本。

版本发布日期距今
2.1.1latest2026/05/135 个月前
1.1.12022/04/274 年前
1.1.02022/02/074 年前
1.0.02020/03/076 年前
0.0.52019/01/147 年前
0.0.42019/01/147 年前

关于 @covve/easy-vcard 的常见问题

@covve/easy-vcard 是什么?

Simple vcard formatter

如何安装 @covve/easy-vcard?

在项目目录运行 npm install @covve/easy-vcard,或使用 pnpm add / yarn add / bun add。

@covve/easy-vcard 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@covve/easy-vcard 支持 ESM 还是 CommonJS?

以 CommonJS 形式发布,可以直接 require();在 ES Module 项目中也可以用 import 引入(Node.js 会把 module.exports 作为默认导出)。

@covve/easy-vcard 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@covve/easy-vcard 可以商用吗?

@covve/easy-vcard 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@covve/easy-vcard 的下载量有多少?

根据 npm 官方下载统计,@covve/easy-vcard 在 2026/10/11 – 2026/11/09 这 30 天内被下载 12,487 次,日均约 416 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@covve/easy-vcard 还在维护吗?

最新版本 2.1.1 发布于 2026/05/13(5 个月前);至今共发布 9 个版本,其中过去 12 个月发布了 1 个;首次发布于 2019/01/09。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。