diff --git a/home/options.go b/home/options.go
index ec789d4f..90d356e8 100644
--- a/home/options.go
+++ b/home/options.go
@@ -40,6 +40,33 @@ type arg struct {
 	updateWithValue func(o options, v string) (options, error)         // the mutator for arguments with parameters
 	updateNoValue   func(o options) (options, error)                   // the mutator for arguments without parameters
 	effect          func(o options, exec string) (f effect, err error) // the side-effect closure generator
+
+	serialize func(o options) []string // the re-serialization function back to arguments (return nil for omit)
+}
+
+// {type}SliceOrNil functions check their parameter of type {type}
+// against its zero value and return nil if the parameter value is
+// zero otherwise they return a string slice of the parameter
+
+func stringSliceOrNil(s string) []string {
+	if s == "" {
+		return nil
+	}
+	return []string{s}
+}
+
+func intSliceOrNil(i int) []string {
+	if i == 0 {
+		return nil
+	}
+	return []string{strconv.Itoa(i)}
+}
+
+func boolSliceOrNil(b bool) []string {
+	if b {
+		return []string{}
+	}
+	return nil
 }
 
 var args []arg
@@ -50,18 +77,21 @@ var configArg = arg{
 	func(o options, v string) (options, error) { o.configFilename = v; return o, nil },
 	nil,
 	nil,
+	func(o options) []string { return stringSliceOrNil(o.configFilename) },
 }
 
 var workDirArg = arg{
 	"Path to the working directory",
 	"work-dir", "w",
 	func(o options, v string) (options, error) { o.workDir = v; return o, nil }, nil, nil,
+	func(o options) []string { return stringSliceOrNil(o.workDir) },
 }
 
 var hostArg = arg{
 	"Host address to bind HTTP server on",
 	"host", "h",
 	func(o options, v string) (options, error) { o.bindHost = v; return o, nil }, nil, nil,
+	func(o options) []string { return stringSliceOrNil(o.bindHost) },
 }
 
 var portArg = arg{
@@ -80,6 +110,7 @@ var portArg = arg{
 		}
 		return o, err
 	}, nil, nil,
+	func(o options) []string { return intSliceOrNil(o.bindPort) },
 }
 
 var serviceArg = arg{
@@ -89,42 +120,49 @@ var serviceArg = arg{
 		o.serviceControlAction = v
 		return o, nil
 	}, nil, nil,
+	func(o options) []string { return stringSliceOrNil(o.serviceControlAction) },
 }
 
 var logfileArg = arg{
 	"Path to log file. If empty: write to stdout; if 'syslog': write to system log",
 	"logfile", "l",
 	func(o options, v string) (options, error) { o.logFile = v; return o, nil }, nil, nil,
+	func(o options) []string { return stringSliceOrNil(o.logFile) },
 }
 
 var pidfileArg = arg{
 	"Path to a file where PID is stored",
 	"pidfile", "",
 	func(o options, v string) (options, error) { o.pidFile = v; return o, nil }, nil, nil,
+	func(o options) []string { return stringSliceOrNil(o.pidFile) },
 }
 
 var checkConfigArg = arg{
 	"Check configuration and exit",
 	"check-config", "",
 	nil, func(o options) (options, error) { o.checkConfig = true; return o, nil }, nil,
+	func(o options) []string { return boolSliceOrNil(o.checkConfig) },
 }
 
 var noCheckUpdateArg = arg{
 	"Don't check for updates",
 	"no-check-update", "",
 	nil, func(o options) (options, error) { o.disableUpdate = true; return o, nil }, nil,
+	func(o options) []string { return boolSliceOrNil(o.disableUpdate) },
 }
 
 var verboseArg = arg{
 	"Enable verbose output",
 	"verbose", "v",
 	nil, func(o options) (options, error) { o.verbose = true; return o, nil }, nil,
+	func(o options) []string { return boolSliceOrNil(o.verbose) },
 }
 
 var glinetArg = arg{
 	"Run in GL-Inet compatibility mode",
 	"glinet", "",
 	nil, func(o options) (options, error) { o.glinetMode = true; return o, nil }, nil,
+	func(o options) []string { return boolSliceOrNil(o.glinetMode) },
 }
 
 var versionArg = arg{
@@ -133,6 +171,7 @@ var versionArg = arg{
 	nil, nil, func(o options, exec string) (effect, error) {
 		return func() error { fmt.Println(version()); os.Exit(0); return nil }, nil
 	},
+	func(o options) []string { return nil },
 }
 
 var helpArg = arg{
@@ -141,6 +180,7 @@ var helpArg = arg{
 	nil, nil, func(o options, exec string) (effect, error) {
 		return func() error { _ = printHelp(exec); os.Exit(64); return nil }, nil
 	},
+	func(o options) []string { return nil },
 }
 
 func init() {
@@ -253,3 +293,21 @@ func parse(exec string, ss []string) (o options, f effect, err error) {
 
 	return
 }
+
+func shortestFlag(a arg) string {
+	if a.shortName != "" {
+		return "-" + a.shortName
+	}
+	return "--" + a.longName
+}
+
+func serialize(o options) []string {
+	ss := []string{}
+	for _, arg := range args {
+		s := arg.serialize(o)
+		if s != nil {
+			ss = append(ss, append([]string{shortestFlag(arg)}, s...)...)
+		}
+	}
+	return ss
+}
diff --git a/home/options_test.go b/home/options_test.go
index 750f3ce2..5a2b1155 100644
--- a/home/options_test.go
+++ b/home/options_test.go
@@ -169,3 +169,69 @@ func TestParseUnknown(t *testing.T) {
 	testParseErr(t, "unknown plus", "+x")
 	testParseErr(t, "unknown dash", "-")
 }
+
+func testSerialize(t *testing.T, o options, ss ...string) {
+	result := serialize(o)
+	if len(result) != len(ss) {
+		t.Fatalf("expected %s but got %s", ss, result)
+	}
+	for i, r := range result {
+		if r != ss[i] {
+			t.Fatalf("expected %s but got %s", ss, result)
+		}
+	}
+}
+
+func TestSerializeEmpty(t *testing.T) {
+	testSerialize(t, options{})
+}
+
+func TestSerializeConfigFilename(t *testing.T) {
+	testSerialize(t, options{configFilename: "path"}, "-c", "path")
+}
+
+func TestSerializeWorkDir(t *testing.T) {
+	testSerialize(t, options{workDir: "path"}, "-w", "path")
+}
+
+func TestSerializeBindHost(t *testing.T) {
+	testSerialize(t, options{bindHost: "addr"}, "-h", "addr")
+}
+
+func TestSerializeBindPort(t *testing.T) {
+	testSerialize(t, options{bindPort: 666}, "-p", "666")
+}
+
+func TestSerializeLogfile(t *testing.T) {
+	testSerialize(t, options{logFile: "path"}, "-l", "path")
+}
+
+func TestSerializePidfile(t *testing.T) {
+	testSerialize(t, options{pidFile: "path"}, "--pidfile", "path")
+}
+
+func TestSerializeCheckConfig(t *testing.T) {
+	testSerialize(t, options{checkConfig: true}, "--check-config")
+}
+
+func TestSerializeDisableUpdate(t *testing.T) {
+	testSerialize(t, options{disableUpdate: true}, "--no-check-update")
+}
+
+func TestSerializeService(t *testing.T) {
+	testSerialize(t, options{serviceControlAction: "run"}, "-s", "run")
+}
+
+func TestSerializeGLInet(t *testing.T) {
+	testSerialize(t, options{glinetMode: true}, "--glinet")
+}
+
+func TestSerializeMultiple(t *testing.T) {
+	testSerialize(t, options{
+		serviceControlAction: "run",
+		configFilename:       "config",
+		workDir:              "work",
+		pidFile:              "pid",
+		disableUpdate:        true,
+	}, "-c", "config", "-w", "work", "-s", "run", "--pidfile", "pid", "--no-check-update")
+}